1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 /** 24 @addtogroup Replication 25 @{ 26 27 @file load_data_events.h 28 29 @brief LOAD DATA INFILE is not written to the binary log like other 30 statements. It is written as one or more events in a packed format, 31 not as a cleartext statement in the binary log. The events indicate 32 what options are present in the statement and how to process the data file. 33 */ 34 35 #ifndef LOAD_DATA_EVENTS_INCLUDED 36 #define LOAD_DATA_EVENTS_INCLUDED 37 38 #include "statement_events.h" 39 #include "table_id.h" 40 41 /* 42 These are flags and structs to handle all the LOAD DATA INFILE options (LINES 43 TERMINATED etc). 44 DUMPFILE_FLAG is probably not used (DUMPFILE is a clause of SELECT, 45 not of LOAD DATA). 46 */ 47 #define DUMPFILE_FLAG 0x1 48 #define OPT_ENCLOSED_FLAG 0x2 49 #define REPLACE_FLAG 0x4 50 #define IGNORE_FLAG 0x8 51 52 #define FIELD_TERM_EMPTY 0x1 53 #define ENCLOSED_EMPTY 0x2 54 #define LINE_TERM_EMPTY 0x4 55 #define LINE_START_EMPTY 0x8 56 #define ESCAPED_EMPTY 0x10 57 58 namespace binary_log 59 { 60 /** 61 @struct old_sql_ex 62 63 This structure holds the single character field/line options in the 64 LOAD_DATA_INFILE statement. It is used for server versions prior to 65 5.0.3, where a single character separator was supported for 66 LOAD_DATA_INFILE statements. 67 68 The structure contains the foloowing components. 69 <table> 70 <caption>old_sql_ex members for Load_event</caption> 71 72 <tr> 73 <th>Name</th> 74 <th>Format</th> 75 <th>Description</th> 76 </tr> 77 78 <tr> 79 <td>field_term</td> 80 <td>a single character</td> 81 <td>field terminating character spcified by the subclause 82 'FIELDS TERMINATED BY' 83 </td> 84 </tr> 85 86 <tr> 87 <td>enclosed</td> 88 <td>a single character</td> 89 <td>character used for enclosing field data, specified by 90 the subclause 'FIELDS ENCLOSED BY' 91 </td> 92 </tr> 93 94 <tr> 95 <td>line_term</td> 96 <td>a single character</td> 97 <td>line terminating character, specified by the subclause 98 'LINES TERMINATED BY' 99 </td> 100 </tr> 101 102 <tr> 103 <td>line_start</td> 104 <td>a single character</td> 105 <td>character indicating the start of a line, specified by 106 the subclause 'LINES STARTING BY' 107 </td> 108 </tr> 109 110 <tr> 111 <td>escaped</td> 112 <td>a single character</td> 113 <td>escape character for a field, specified by the subclause 114 'FIELD ESCAPED BY' 115 </td> 116 </tr> 117 118 <tr> 119 <td>opt_flags</td> 120 <td>8 bit bitfield value </td> 121 <td>bitfield indicating the presence of the keywords REPLACE, 122 IGNORE, and OPTIONALLY 123 </td> 124 </tr> 125 126 <tr> 127 <td>empty_flags</td> 128 <td>8 bit bitfield value </td> 129 <td>The low 5 bits of empty_flags indicate which of the five strings 130 have length 0. For each of the following flags that is set, the 131 corresponding string has length 0; for the flags that are not set, 132 the string has length 1: FIELD_TERM_EMPTY==0x1, 133 ENCLOSED_EMPTY==0x2, LINE_TERM_EMPTY==0x4, LINE_START_EMPTY==0x8, 134 ESCAPED_EMPTY==0x10. 135 </td> 136 </tr> 137 */ 138 struct old_sql_ex 139 { 140 char field_term; 141 char enclosed; 142 char line_term; 143 char line_start; 144 char escaped; 145 char opt_flags; 146 char empty_flags; 147 }; 148 149 /** 150 @struct sql_ex_data_info 151 152 This structure holds the multi character field/line options in the 153 LOAD_DATA_INFILE statement. It is used for server versions newer than 154 5.0.3, where multicharacter separators were supported for 155 LOAD_DATA_INFILE SQL Query. 156 157 The structure is simlar to old_sql_ex defined above. 158 The new and old format differ in the way the five strings indicating the 159 terminating characters in the query are stored. 160 161 To know more, read comments in the class Load_event and struct 162 old_sql_ex. 163 */ 164 struct sql_ex_data_info 165 { sql_ex_data_infosql_ex_data_info166 sql_ex_data_info() 167 : cached_new_format(0) 168 { 169 } 170 const char* field_term; 171 const char* enclosed; 172 const char* line_term; 173 const char* line_start; 174 const char* escaped; 175 uint8_t field_term_len, enclosed_len, line_term_len, 176 line_start_len, escaped_len; 177 178 char opt_flags; 179 char empty_flags; 180 181 int cached_new_format; 182 183 /** store in new format even if old is possible */ force_new_formatsql_ex_data_info184 void force_new_format() { cached_new_format = 1;} data_sizesql_ex_data_info185 int data_size() 186 { 187 return (new_format() ? 188 field_term_len + enclosed_len + line_term_len + 189 line_start_len + escaped_len + 6 : 7); 190 } 191 const char* init(const char* buf, const char* buf_end, bool use_new_format); new_formatsql_ex_data_info192 bool new_format() 193 { 194 return ((cached_new_format != -1) ? cached_new_format : 195 (cached_new_format= (field_term_len > 1 || 196 enclosed_len > 1 || 197 line_term_len > 1 || line_start_len > 1 || 198 escaped_len > 1))); 199 } 200 }; 201 202 /** 203 Elements of this enum describe how LOAD DATA handles duplicates. 204 */ 205 enum enum_load_dup_handling 206 { 207 LOAD_DUP_ERROR= 0, 208 LOAD_DUP_IGNORE, 209 LOAD_DUP_REPLACE 210 }; 211 212 /** 213 @class Execute_load_query_event 214 215 Event responsible for LOAD DATA execution, it similar to Query_event 216 but before executing the query it substitutes original filename in LOAD DATA 217 query with name of temporary file. 218 219 The first 13 bytes of the Post-Header for this event are the same as for 220 Query_event, as is the initial status variable block in the Body. 221 222 @section Execute_load_query_event_binary_format Binary Format 223 224 The additional members of the events are the following: 225 226 <table> 227 <caption>Body for Execute_load_query_event</caption> 228 229 <tr> 230 <th>Name</th> 231 <th>Format</th> 232 <th>Description</th> 233 </tr> 234 235 <tr> 236 <td>file_id</td> 237 <td>4 byte unsigned integer</td> 238 <td>ID of the temporary file to load</td> 239 </tr> 240 241 <tr> 242 <td>fn_pos_start</td> 243 <td>4 byte unsigned integer</td> 244 <td>The start position within the statement for filename substitution</td> 245 </tr> 246 <tr> 247 248 <td>fn_pos_end</td> 249 <td>4 byte unsigned integer</td> 250 <td>The end position within the statement for filename substitution</td> 251 </tr> 252 253 <tr> 254 <td>dup_handling</td> 255 <td>enum_load_dup_handling</td> 256 <td>Represents information on how to handle duplicates: 257 LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE= 1, LOAD_DUP_REPLACE= 2</td> 258 </tr> 259 */ 260 class Execute_load_query_event : public virtual Query_event 261 { 262 public: 263 enum Execute_load_query_event_offset{ 264 /** ELQ = "Execute Load Query" */ 265 ELQ_FILE_ID_OFFSET= QUERY_HEADER_LEN, 266 ELQ_FN_POS_START_OFFSET= ELQ_FILE_ID_OFFSET + 4, 267 ELQ_FN_POS_END_OFFSET= ELQ_FILE_ID_OFFSET + 8, 268 ELQ_DUP_HANDLING_OFFSET= ELQ_FILE_ID_OFFSET + 12 269 }; 270 271 int32_t file_id; /** file_id of temporary file */ 272 uint32_t fn_pos_start; /** pointer to the part of the query that should 273 be substituted */ 274 uint32_t fn_pos_end; /** pointer to the end of this part of query */ 275 276 /** 277 We have to store type of duplicate handling explicitly, because 278 for LOAD DATA it also depends on LOCAL option. And this part 279 of query will be rewritten during replication so this information 280 may be lost... 281 */ 282 enum_load_dup_handling dup_handling; 283 284 Execute_load_query_event(uint32_t file_id_arg, uint32_t fn_pos_start, 285 uint32_t fn_pos_end, enum_load_dup_handling dup); 286 287 /** 288 The constructor receives a buffer and instantiates a Execute_load_uery_event 289 filled in with the data from the buffer. 290 291 <pre> 292 The fixed event data part buffer layout is as follows: 293 +---------------------------------------------------------------------+ 294 | thread_id | query_exec_time | db_len | error_code | status_vars_len | 295 +---------------------------------------------------------------------+ 296 +----------------------------------------------------+ 297 | file_id | fn_pos_start | fn_pos_end | dup_handling | 298 +----------------------------------------------------+ 299 </pre> 300 301 <pre> 302 The fixed event data part buffer layout is as follows: 303 +------------------------------------------------------------------+ 304 | Zero or more status variables | db | LOAD DATA INFILE statement | 305 +------------------------------------------------------------------+ 306 </pre> 307 308 @param buf Contains the serialized event. 309 @param length Length of the serialized event. 310 @param description_event An FDE event, used to get the 311 following information 312 -binlog_version 313 -server_version 314 -post_header_len 315 -common_header_len 316 The content of this object 317 depends on the binlog-version currently in use. 318 @param event_type Required to determine whether the event type is 319 QUERY_EVENT or EXECUTE_LOAD_QUERY_EVENT 320 */ 321 Execute_load_query_event(const char* buf, unsigned int event_len, 322 const Format_description_event *description_event); 323 ~Execute_load_query_event()324 ~Execute_load_query_event() {} 325 326 }; 327 328 /** 329 @class Load_event 330 331 This event corresponds to a "LOAD DATA INFILE" SQL query in the 332 following form: 333 334 @verbatim 335 (1) USE db; 336 (2) LOAD DATA [CONCURRENT] [LOCAL] INFILE 'file_name' 337 (3) [REPLACE | IGNORE] 338 (4) INTO TABLE 'table_name' 339 (5) [FIELDS 340 (6) [TERMINATED BY 'field_term'] 341 (7) [[OPTIONALLY] ENCLOSED BY 'enclosed'] 342 (8) [ESCAPED BY 'escaped'] 343 (9) ] 344 (10) [LINES 345 (11) [TERMINATED BY 'line_term'] 346 (12) [LINES STARTING BY 'line_start'] 347 (13) ] 348 (14) [IGNORE skip_lines LINES] 349 (15) (field_1, field_2, ..., field_n) 350 @endverbatim 351 352 @section Load_event_binary_format Binary Format 353 354 The Post-Header consists of the following six components. 355 356 <table> 357 <caption>Post-Header for Load_event</caption> 358 359 <tr> 360 <th>Name</th> 361 <th>Format</th> 362 <th>Description</th> 363 </tr> 364 365 <tr> 366 <td>slave_proxy_id</td> 367 <td>4 byte unsigned integer</td> 368 <td>An integer identifying the client thread that issued the 369 query. The id is unique per server. (Note, however, that two 370 threads on different servers may have the same slave_proxy_id.) 371 This is used when a client thread creates a temporary table local 372 to the client. The slave_proxy_id is used to distinguish 373 temporary tables that belong to different clients. 374 </td> 375 </tr> 376 377 <tr> 378 <td>load_exec_time</td> 379 <td>4 byte unsigned integer</td> 380 <td>The time from when the query started to when it was logged in 381 the binlog, in seconds.</td> 382 </tr> 383 384 <tr> 385 <td>skip_lines</td> 386 <td>4 byte unsigned integer</td> 387 <td>The number on line (14) above, if present, or 0 if line (14) 388 is left out. 389 </td> 390 </tr> 391 392 <tr> 393 <td>table_name_len</td> 394 <td>1 byte unsigned integer</td> 395 <td>The length of 'table_name' on line (4) above.</td> 396 </tr> 397 398 <tr> 399 <td>db_len</td> 400 <td>1 byte unsigned integer</td> 401 <td>The length of 'db' on line (1) above.</td> 402 </tr> 403 404 <tr> 405 <td>num_fields</td> 406 <td>4 byte unsigned integer</td> 407 <td>The number n of fields on line (15) above.</td> 408 </tr> 409 </table> 410 411 The Body contains the following components. 412 413 <table> 414 <caption>Body of Load_event</caption> 415 416 <tr> 417 <th>Name</th> 418 <th>Format</th> 419 <th>Description</th> 420 </tr> 421 422 <tr> 423 <td>sql_ex</td> 424 <td>variable length</td> 425 426 <td>Describes the part of the query on lines (3) and 427 (5)–(13) above. More precisely, it stores the five strings 428 (on lines) field_term (6), enclosed (7), escaped (8), line_term 429 (11), and line_start (12); as well as a bitfield indicating the 430 presence of the keywords REPLACE (3), IGNORE (3), and OPTIONALLY 431 (7). 432 433 The data is stored in one of two formats, called "old" and "new". 434 The type field of Common-Header determines which of these two 435 formats is used: type LOAD_EVENT means that the old format is 436 used, and type NEW_LOAD_EVENT means that the new format is used. 437 When MySQL writes a Load_event, it uses the new format if at 438 least one of the five strings is two or more bytes long. 439 Otherwise (i.e., if all strings are 0 or 1 bytes long), the old 440 format is used. 441 442 The new and old format differ in the way the five strings are 443 stored. 444 445 <ul> 446 <li> In the new format, the strings are stored in the order 447 field_term, enclosed, escaped, line_term, line_start. Each string 448 consists of a length (1 byte), followed by a sequence of 449 characters (0-255 bytes). Finally, a boolean combination of the 450 following flags is stored in 1 byte: REPLACE_FLAG==0x4, 451 IGNORE_FLAG==0x8, and OPT_ENCLOSED_FLAG==0x2. If a flag is set, 452 it indicates the presence of the corresponding keyword in the SQL 453 query. 454 455 <li> In the old format, we know that each string has length 0 or 456 1. Therefore, only the first byte of each string is stored. The 457 order of the strings is the same as in the new format. These five 458 bytes are followed by the same 1 byte bitfield as in the new 459 format. Finally, a 1 byte bitfield called empty_flags is stored. 460 The low 5 bits of empty_flags indicate which of the five strings 461 have length 0. For each of the following flags that is set, the 462 corresponding string has length 0; for the flags that are not set, 463 the string has length 1: FIELD_TERM_EMPTY==0x1, 464 ENCLOSED_EMPTY==0x2, LINE_TERM_EMPTY==0x4, LINE_START_EMPTY==0x8, 465 ESCAPED_EMPTY==0x10. 466 </ul> 467 468 Thus, the size of the new format is 6 bytes + the sum of the sizes 469 of the five strings. The size of the old format is always 7 470 bytes. 471 </td> 472 </tr> 473 474 <tr> 475 <td>field_lens</td> 476 <td>num_fields 1 byte unsigned integers</td> 477 <td>An array of num_fields integers representing the length of 478 each field in the query. (num_fields is from the Post-Header). 479 </td> 480 </tr> 481 482 <tr> 483 <td>fields</td> 484 <td>num_fields null-terminated strings</td> 485 <td>An array of num_fields null-terminated strings, each 486 representing a field in the query. (The trailing zero is 487 redundant, since the length are stored in the num_fields array.) 488 The total length of all strings equals to the sum of all 489 field_lens, plus num_fields bytes for all the trailing zeros. 490 </td> 491 </tr> 492 493 <tr> 494 <td>table_name</td> 495 <td>null-terminated string of length table_len + 1 bytes</td> 496 <td>The 'table_name' from the query, as a null-terminated string. 497 (The trailing zero is actually redundant since the table_len is 498 known from Post-Header.) 499 </td> 500 </tr> 501 502 <tr> 503 <td>db</td> 504 <td>null-terminated string of length db_len + 1 bytes</td> 505 <td>The 'db' from the query, as a null-terminated string. 506 (The trailing zero is actually redundant since the db_len is known 507 from Post-Header.) 508 </td> 509 </tr> 510 511 <tr> 512 <td>fname</td> 513 <td>variable length string without trailing zero, extending to the 514 end of the event (determined by the length field of the 515 Common-Header) 516 </td> 517 <td>The 'file_name' from the query. 518 </td> 519 </tr> 520 521 </table> 522 523 @subsection Load_event_notes_on_previous_versions Notes on Previous Versions 524 525 This event type is understood by current versions, but only 526 generated by MySQL 3.23 and earlier. 527 */ 528 class Load_event: public Binary_log_event 529 { 530 protected: 531 int copy_load_event(const char *buf, unsigned long event_len, 532 int body_offset, 533 const Format_description_event* description_event); 534 // Required by Load_event(THD* ...) in the server 535 explicit Load_event(Log_event_type type_code_arg= NEW_LOAD_EVENT) Binary_log_event(type_code_arg)536 : Binary_log_event(type_code_arg), 537 num_fields(0), 538 fields(0), 539 field_lens(0), 540 field_block_len(0) 541 {} 542 public: 543 enum Load_event_offset { 544 L_THREAD_ID_OFFSET= 0, 545 L_EXEC_TIME_OFFSET= 4, 546 L_SKIP_LINES_OFFSET= 8, 547 L_TBL_LEN_OFFSET= 12, 548 L_DB_LEN_OFFSET= 13, 549 L_NUM_FIELDS_OFFSET= 14, 550 L_SQL_EX_OFFSET= 18, 551 L_DATA_OFFSET= LOAD_HEADER_LEN 552 }; 553 554 /** 555 This is the execution time stored in the post header. 556 Make sure to use it to set the exec_time variable in class Log_event 557 */ 558 uint32_t load_exec_time; 559 560 uint32_t slave_proxy_id; 561 size_t table_name_len; 562 563 /** 564 No need to have a catalog, as these events can only come from 4.x. 565 */ 566 size_t db_len; 567 size_t fname_len; 568 uint32_t num_fields; 569 570 const char* fields; 571 const unsigned char* field_lens; 572 uint32_t field_block_len; 573 574 const char* table_name; 575 const char* db; 576 const char* fname; 577 uint32_t skip_lines; 578 sql_ex_data_info sql_ex_data; 579 bool local_fname; 580 581 /** 582 Indicates that this event corresponds to LOAD DATA CONCURRENT, 583 584 @note Since Load_event event coming from the binary log 585 lacks information whether LOAD DATA on master was concurrent 586 or not, this flag is only set to TRUE for an auxiliary 587 Load_event object which is used in mysql_load() to 588 re-construct LOAD DATA statement from function parameters, 589 for logging. 590 */ 591 bool is_concurrent; 592 593 /** 594 Note that for all the events related to LOAD DATA (Load_event, 595 Create_file/Append/Exec/Delete, we pass description_event; however as 596 logging of LOAD DATA is changed, this is only used 597 for the common_header_len (post_header_len is not changed). 598 599 <pre> 600 The fixed event data part buffer layout is as follows: 601 +--------------------------------------------------------------------------------+ 602 | thread_id | load_exec_time | skip_lines | table_name_len | db_len | num_fields | 603 +--------------------------------------------------------------------------------+ 604 </pre> 605 606 <pre> 607 Variable data part 608 +---------------------------------------------------------------------+ 609 | sql_ex_data struct | len of col names to load | col_names | tb_name | 610 +-------------------------------------------------------------- ------+ 611 +----------------+ 612 |db_name | fname | 613 +----------------+ 614 </pre> 615 @param buf Contains the serialized event. 616 @param length Length of the serialized event. 617 @param description_event An FDE event, used to get the 618 following information 619 -binlog_version 620 -server_version 621 -post_header_len 622 -common_header_len 623 The content of this object 624 depends on the binlog-version currently in use. 625 */ 626 Load_event(const char* buf, unsigned int event_len, 627 const Format_description_event* description_event); 628 ~Load_event()629 ~Load_event() 630 { 631 } 632 get_data_size()633 size_t get_data_size() 634 { 635 return (table_name_len + db_len + 2 + fname_len 636 + static_cast<unsigned int>(LOAD_HEADER_LEN) 637 + sql_ex_data.data_size() + field_block_len + num_fields); 638 } 639 #ifndef HAVE_MYSYS 640 //TODO(WL#7684): Implement the method print_event_info and print_long_info for 641 // all the events supported in MySQL Binlog print_event_info(std::ostream & info)642 void print_event_info(std::ostream& info) {}; print_long_info(std::ostream & info)643 void print_long_info(std::ostream& info) {}; 644 #endif 645 646 }; 647 648 /* the classes below are for the new LOAD DATA INFILE logging */ 649 650 /** 651 @class Create_file_event 652 653 The Create_file_event contains the options to LOAD DATA INFILE. 654 This was a design flaw since the file cannot be loaded until the 655 Exec_load_event is seen. The use of this event was deprecated from 656 MySQL server version 5.0.3 and above. 657 658 @section Create_file_event_binary_format Binary Format 659 660 The post header contains the following: 661 662 <table> 663 <caption>Post header for Create_file_event</caption> 664 665 <tr> 666 <th>Name</th> 667 <th>Format</th> 668 <th>Description</th> 669 </tr> 670 671 <tr> 672 <td>file_id</td> 673 <td>32 bit integer</td> 674 <td>The ID of the temporary file created by the slave to which 675 the first data block is copied</td> 676 </tr> 677 </table> 678 */ 679 class Create_file_event: public virtual Load_event 680 { 681 protected: 682 /** 683 Pretend we are Load event, so we can write out just 684 our Load part - used on the slave when writing event out to 685 SQL_LOAD-*.info file 686 */ 687 bool fake_base; 688 public: 689 enum Create_file_offset { 690 /** CF = "Create File" */ 691 CF_FILE_ID_OFFSET= 0, 692 CF_DATA_OFFSET= CREATE_FILE_HEADER_LEN 693 }; 694 695 unsigned char* block; 696 const char *event_buf; 697 unsigned int block_len; 698 unsigned int file_id; 699 bool inited_from_old; 700 701 /** 702 The buffer layout for variable data part is as follows: 703 <pre> 704 +-------------------------------------------------------------------+ 705 | name_len | name | is_null | type | charset_number | val_len | val | 706 +-------------------------------------------------------------------+ 707 </pre> 708 709 @param buf Contains the serialized event. 710 @param length Length of the serialized event. 711 @param description_event An FDE event, used to get the 712 following information 713 -binlog_version 714 -server_version 715 -post_header_len 716 -common_header_len 717 The content of this object 718 depends on the binlog-version currently in use. 719 */ 720 Create_file_event(const char* buf, unsigned int event_len, 721 const Format_description_event* description_event); 722 723 ~Create_file_event()724 ~Create_file_event() 725 { 726 bapi_free(const_cast<char*>(event_buf)); 727 } get_data_size()728 size_t get_data_size() 729 { 730 return (fake_base ? Load_event::get_data_size() : 731 Load_event::get_data_size() + 732 4 + 1 + block_len); 733 } 734 735 736 }; 737 738 /** 739 @class Delete_file_event 740 741 DELETE_FILE_EVENT occurs when the LOAD DATA failed on the master. 742 This event notifies the slave not to do the load and to delete 743 the temporary file. 744 745 @section Delete_file_event_binary_format Binary Format 746 747 The variable data part is empty. The post header contains the following: 748 749 <table> 750 <caption>Post header for Delete_file_event</caption> 751 752 <tr> 753 <th>Name</th> 754 <th>Format</th> 755 <th>Description</th> 756 </tr> 757 758 <tr> 759 <td>file_id</td> 760 <td>32 bit integer</td> 761 <td>The ID of the file to be deleted</td> 762 </tr> 763 </table> 764 */ 765 class Delete_file_event: public Binary_log_event 766 { 767 protected: 768 // Required by Delete_file_log_event(THD* ..) Delete_file_event(uint32_t file_id_arg,const char * db_arg)769 Delete_file_event(uint32_t file_id_arg, const char* db_arg) 770 : Binary_log_event(DELETE_FILE_EVENT), 771 file_id(file_id_arg), 772 db(db_arg) 773 {} 774 public: 775 enum Delete_file_offset { 776 /** DF = "Delete File" */ 777 DF_FILE_ID_OFFSET= 0 778 }; 779 780 uint32_t file_id; 781 const char* db; /** see comment in Append_block_event */ 782 783 /** 784 The buffer layout for fixed data part is as follows: 785 <pre> 786 +---------+ 787 | file_id | 788 +---------+ 789 </pre> 790 791 @param buf Contains the serialized event. 792 @param length Length of the serialized event. 793 @param description_event An FDE event, used to get the 794 following information 795 -binlog_version 796 -server_version 797 -post_header_len 798 -common_header_len 799 The content of this object 800 depends on the binlog-version currently in use. 801 */ 802 Delete_file_event(const char* buf, unsigned int event_len, 803 const Format_description_event* description_event); 804 ~Delete_file_event()805 ~Delete_file_event() {} 806 807 #ifndef HAVE_MYSYS 808 //TODO(WL#7684): Implement the method print_event_info and print_long_info for 809 // all the events supported in MySQL Binlog print_event_info(std::ostream & info)810 void print_event_info(std::ostream& info) {}; print_long_info(std::ostream & info)811 void print_long_info(std::ostream& info) {}; 812 #endif 813 }; 814 815 /** 816 @class Execute_load_event 817 818 Execute_load_event is created when the LOAD_DATA query succeeds on 819 the master. The slave should be notified to load the temporary file into 820 the table. For server versions > 5.0.3, the temporary files that stores 821 the parameters to LOAD DATA INFILE is not needed anymore, since they are 822 stored in this event. There is still a temp file containing all the data 823 to be loaded. 824 825 @section Execute_load_event_binary_format Binary Format 826 827 The variable data part is empty. The post header contains the following: 828 829 <table> 830 <caption>Post header for Execute_load_event</caption> 831 832 <tr> 833 <th>Name</th> 834 <th>Format</th> 835 <th>Description</th> 836 </tr> 837 838 <tr> 839 <td>file_id</td> 840 <td>32 bit integer</td> 841 <td>The ID of the file to load</td> 842 </tr> 843 */ 844 class Execute_load_event: public Binary_log_event 845 { 846 protected: 847 Execute_load_event(const uint32_t file_id, const char* db_arg); get_type_code()848 Log_event_type get_type_code() { return EXEC_LOAD_EVENT;} 849 850 public: 851 enum Execute_load_offset { 852 /** EL = "Execute Load" */ 853 EL_FILE_ID_OFFSET= 0 854 }; 855 856 uint32_t file_id; 857 const char* db; /** see comment in Append_block_event */ 858 859 /** 860 The buffer layout for fixed data part is as follows: 861 <pre> 862 +---------+ 863 | file_id | 864 +---------+ 865 </pre> 866 867 @param buf Contains the serialized event. 868 @param length Length of the serialized event. 869 @param description_event An FDE event, used to get the 870 following information 871 -binlog_version 872 -server_version 873 -post_header_len 874 -common_header_len 875 The content of this object 876 depends on the binlog-version currently in use. 877 */ 878 Execute_load_event(const char* buf, unsigned int event_len, 879 const Format_description_event *description_event); 880 ~Execute_load_event()881 ~Execute_load_event() {} 882 883 #ifndef HAVE_MYSYS 884 //TODO(WL#7684): Implement the method print_event_info and print_long_info for 885 // all the events supported in MySQL Binlog print_event_info(std::ostream & info)886 void print_event_info(std::ostream& info) {}; print_long_info(std::ostream & info)887 void print_long_info(std::ostream& info) {}; 888 #endif 889 }; 890 891 /** 892 @class Append_block_event 893 894 This event is created to contain the file data. One LOAD_DATA_INFILE 895 can have 0 or more instances of this event written to the binary log 896 depending on the size of the file. If the file to be loaded is greater 897 than the threshold value, which is roughly 2^17 bytes, the file is 898 divided into blocks of size equal to the threshold, and each block 899 is sent across as a separate event. 900 901 @section Append_block_event_binary_format Binary Format 902 903 The post header contains the following: 904 905 <table> 906 <caption>Post header for Append_block_event</caption> 907 908 <tr> 909 <th>Name</th> 910 <th>Format</th> 911 <th>Description</th> 912 </tr> 913 914 <tr> 915 <td>file_id</td> 916 <td>32 bit integer</td> 917 <td>The ID of the file to append the block to</td> 918 </tr> 919 </table> 920 921 The body of the event contains the raw data to load. The raw data 922 size is the event size minus the size of all the fixed event parts. 923 */ 924 class Append_block_event: public Binary_log_event 925 { 926 protected: 927 /** 928 This constructor is used by the MySQL server. 929 */ Append_block_event(const char * db_arg,unsigned char * block_arg,unsigned int block_len_arg,uint32_t file_id_arg)930 Append_block_event(const char* db_arg, 931 unsigned char* block_arg, 932 unsigned int block_len_arg, 933 uint32_t file_id_arg) 934 : Binary_log_event(APPEND_BLOCK_EVENT), 935 block(block_arg), block_len(block_len_arg), 936 file_id(file_id_arg), db(db_arg) 937 {} 938 939 Append_block_event(Log_event_type type_arg= APPEND_BLOCK_EVENT) Binary_log_event(type_arg)940 : Binary_log_event(type_arg) 941 {} 942 943 public: 944 enum Append_block_offset 945 { 946 /** AB = "Append Block" */ 947 AB_FILE_ID_OFFSET= 0, 948 AB_DATA_OFFSET= APPEND_BLOCK_HEADER_LEN 949 }; 950 951 unsigned char* block; 952 unsigned int block_len; 953 uint32_t file_id; 954 /** 955 'db' is filled when the event is created in mysql_load() (the 956 event needs to have a 'db' member to be well filtered by 957 binlog-*-db rules). 'db' is not written to the binlog (it's not 958 used by Append_block_log_event::write()), so it can't be read in 959 the Append_block_event(const char* buf, int event_len) 960 constructor. In other words, 'db' is used only for filtering by 961 binlog-*-db rules. Create_file_event is different: it's 'db' 962 (which is inherited from Load_event) is written to the binlog 963 and can be re-read. 964 */ 965 const char* db; 966 967 968 /** 969 The buffer layout for fixed data part is as follows: 970 <pre> 971 +---------+ 972 | file_id | 973 +---------+ 974 </pre> 975 976 The buffer layout for variabl data part is as follows: 977 <pre> 978 +-------------------+ 979 | block | block_len | 980 +-------------------+ 981 </pre> 982 983 @param buf Contains the serialized event. 984 @param length Length of the serialized event. 985 @param description_event An FDE event, used to get the 986 following information 987 -binlog_version 988 -server_version 989 -post_header_len 990 -common_header_len 991 The content of this object 992 depends on the binlog-version currently in use. 993 */ 994 Append_block_event(const char* buf, unsigned int event_len, 995 const Format_description_event *description_event); ~Append_block_event()996 ~Append_block_event() {} 997 998 #ifndef HAVE_MYSYS 999 //TODO(WL#7684): Implement the method print_event_info and print_long_info for 1000 // all the events supported in MySQL Binlog print_event_info(std::ostream & info)1001 void print_event_info(std::ostream& info) {}; print_long_info(std::ostream & info)1002 void print_long_info(std::ostream& info) {}; 1003 #endif 1004 }; 1005 1006 /** 1007 @class Begin_load_query_event 1008 1009 Event for the first block of file to be loaded, its only difference from 1010 Append_block event is that this event creates or truncates existing file 1011 before writing data. 1012 1013 @section Begin_load_query_event_binary_format Binary Format 1014 1015 The Post-Header and Body for this event type are empty; it only has 1016 the Common-Header. 1017 */ 1018 class Begin_load_query_event: public virtual Append_block_event 1019 { 1020 protected: Begin_load_query_event()1021 Begin_load_query_event() 1022 : Append_block_event(BEGIN_LOAD_QUERY_EVENT) 1023 {} 1024 1025 public: 1026 1027 /** 1028 The buffer layout for fixed data part is as follows: 1029 <pre> 1030 +---------+ 1031 | file_id | 1032 +---------+ 1033 </pre> 1034 1035 The buffer layout for variabl data part is as follows: 1036 <pre> 1037 +-------------------+ 1038 | block | block_len | 1039 +-------------------+ 1040 </pre> 1041 1042 @param buf Contains the serialized event. 1043 @param length Length of the serialized event. 1044 @param description_event An FDE event, used to get the 1045 following information 1046 -binlog_version 1047 -server_version 1048 -post_header_len 1049 -common_header_len 1050 The content of this object 1051 depends on the binlog-version currently in use. 1052 */ 1053 Begin_load_query_event(const char* buf, unsigned int event_len, 1054 const Format_description_event *description_event); 1055 ~Begin_load_query_event()1056 ~Begin_load_query_event() {} 1057 1058 #ifndef HAVE_MYSYS 1059 //TODO(WL#7684): Implement the method print_event_info and print_long_info for 1060 // all the events supported in MySQL Binlog print_event_info(std::ostream & info)1061 void print_event_info(std::ostream& info) {}; print_long_info(std::ostream & info)1062 void print_long_info(std::ostream& info) {}; 1063 #endif 1064 }; 1065 } // end namespace binary_log 1066 /** 1067 @} (end of group Replication) 1068 */ 1069 #endif /* LOAD_DATA_EVENTS_INCLUDED */ 1070