load_data_events.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License, version 2.0,
  4. as published by the Free Software Foundation.
  5. This program is also distributed with certain software (including
  6. but not limited to OpenSSL) that is licensed under separate terms,
  7. as designated in a particular file or component or in included license
  8. documentation. The authors of MySQL hereby grant you an additional
  9. permission to link the program and your derivative works with the
  10. separately licensed software that they have included with MySQL.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License, version 2.0, for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
  18. /**
  19. @addtogroup Replication
  20. @{
  21. @file load_data_events.h
  22. @brief LOAD DATA INFILE is not written to the binary log like other
  23. statements. It is written as one or more events in a packed format,
  24. not as a cleartext statement in the binary log. The events indicate
  25. what options are present in the statement and how to process the data file.
  26. */
  27. #ifndef LOAD_DATA_EVENTS_INCLUDED
  28. #define LOAD_DATA_EVENTS_INCLUDED
  29. #include <sys/types.h>
  30. #include "statement_events.h"
  31. #include "table_id.h"
  32. /*
  33. These are flags and structs to handle all the LOAD DATA INFILE options (LINES
  34. TERMINATED etc).
  35. DUMPFILE_FLAG is probably not used (DUMPFILE is a clause of SELECT,
  36. not of LOAD DATA).
  37. */
  38. #define DUMPFILE_FLAG 0x1
  39. #define OPT_ENCLOSED_FLAG 0x2
  40. #define REPLACE_FLAG 0x4
  41. #define IGNORE_FLAG 0x8
  42. #define FIELD_TERM_EMPTY 0x1
  43. #define ENCLOSED_EMPTY 0x2
  44. #define LINE_TERM_EMPTY 0x4
  45. #define LINE_START_EMPTY 0x8
  46. #define ESCAPED_EMPTY 0x10
  47. namespace binary_log {
  48. /**
  49. Elements of this enum describe how LOAD DATA handles duplicates.
  50. */
  51. enum enum_load_dup_handling {
  52. LOAD_DUP_ERROR = 0,
  53. LOAD_DUP_IGNORE,
  54. LOAD_DUP_REPLACE
  55. };
  56. /**
  57. @class Execute_load_query_event
  58. Event responsible for LOAD DATA execution, it similar to Query_event
  59. but before executing the query it substitutes original filename in LOAD DATA
  60. query with name of temporary file.
  61. The first 13 bytes of the Post-Header for this event are the same as for
  62. Query_event, as is the initial status variable block in the Body.
  63. @section Execute_load_query_event_binary_format Binary Format
  64. The additional members of the events are the following:
  65. <table>
  66. <caption>Body for Execute_load_query_event</caption>
  67. <tr>
  68. <th>Name</th>
  69. <th>Format</th>
  70. <th>Description</th>
  71. </tr>
  72. <tr>
  73. <td>file_id</td>
  74. <td>4 byte unsigned integer</td>
  75. <td>ID of the temporary file to load</td>
  76. </tr>
  77. <tr>
  78. <td>fn_pos_start</td>
  79. <td>4 byte unsigned integer</td>
  80. <td>The start position within the statement for filename substitution</td>
  81. </tr>
  82. <tr>
  83. <td>fn_pos_end</td>
  84. <td>4 byte unsigned integer</td>
  85. <td>The end position within the statement for filename substitution</td>
  86. </tr>
  87. <tr>
  88. <td>dup_handling</td>
  89. <td>enum_load_dup_handling</td>
  90. <td>Represents information on how to handle duplicates:
  91. LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE= 1, LOAD_DUP_REPLACE= 2</td>
  92. </tr>
  93. </table>
  94. */
  95. class Execute_load_query_event : public virtual Query_event {
  96. public:
  97. enum Execute_load_query_event_offset {
  98. /** ELQ = "Execute Load Query" */
  99. ELQ_FILE_ID_OFFSET = QUERY_HEADER_LEN,
  100. ELQ_FN_POS_START_OFFSET = ELQ_FILE_ID_OFFSET + 4,
  101. ELQ_FN_POS_END_OFFSET = ELQ_FILE_ID_OFFSET + 8,
  102. ELQ_DUP_HANDLING_OFFSET = ELQ_FILE_ID_OFFSET + 12
  103. };
  104. int32_t file_id; /** file_id of temporary file */
  105. uint32_t fn_pos_start; /** pointer to the part of the query that should
  106. be substituted */
  107. uint32_t fn_pos_end; /** pointer to the end of this part of query */
  108. /**
  109. We have to store type of duplicate handling explicitly, because
  110. for LOAD DATA it also depends on LOCAL option. And this part
  111. of query will be rewritten during replication so this information
  112. may be lost...
  113. */
  114. enum_load_dup_handling dup_handling;
  115. Execute_load_query_event(uint32_t file_id_arg, uint32_t fn_pos_start,
  116. uint32_t fn_pos_end, enum_load_dup_handling dup);
  117. /**
  118. The constructor receives a buffer and instantiates a
  119. Execute_load_query_event filled in with the data from the buffer.
  120. <pre>
  121. The fixed event data part buffer layout is as follows:
  122. +---------------------------------------------------------------------+
  123. | thread_id | query_exec_time | db_len | error_code | status_vars_len |
  124. +---------------------------------------------------------------------+
  125. +----------------------------------------------------+
  126. | file_id | fn_pos_start | fn_pos_end | dup_handling |
  127. +----------------------------------------------------+
  128. </pre>
  129. <pre>
  130. The fixed event data part buffer layout is as follows:
  131. +------------------------------------------------------------------+
  132. | Zero or more status variables | db | LOAD DATA INFILE statement |
  133. +------------------------------------------------------------------+
  134. </pre>
  135. @param buf Contains the serialized event.
  136. @param fde An FDE event (see Rotate_event constructor for more info).
  137. */
  138. Execute_load_query_event(const char *buf,
  139. const Format_description_event *fde);
  140. ~Execute_load_query_event() {}
  141. };
  142. /**
  143. @class Delete_file_event
  144. DELETE_FILE_EVENT occurs when the LOAD DATA failed on the master.
  145. This event notifies the slave not to do the load and to delete
  146. the temporary file.
  147. @section Delete_file_event_binary_format Binary Format
  148. The variable data part is empty. The post header contains the following:
  149. <table>
  150. <caption>Post header for Delete_file_event</caption>
  151. <tr>
  152. <th>Name</th>
  153. <th>Format</th>
  154. <th>Description</th>
  155. </tr>
  156. <tr>
  157. <td>file_id</td>
  158. <td>32 bit integer</td>
  159. <td>The ID of the file to be deleted</td>
  160. </tr>
  161. </table>
  162. */
  163. class Delete_file_event : public Binary_log_event {
  164. protected:
  165. // Required by Delete_file_log_event(THD* ..)
  166. Delete_file_event(uint32_t file_id_arg, const char *db_arg)
  167. : Binary_log_event(DELETE_FILE_EVENT), file_id(file_id_arg), db(db_arg) {}
  168. public:
  169. enum Delete_file_offset {
  170. /** DF = "Delete File" */
  171. DF_FILE_ID_OFFSET = 0
  172. };
  173. uint32_t file_id;
  174. const char *db; /** see comment in Append_block_event */
  175. /**
  176. The buffer layout for fixed data part is as follows:
  177. <pre>
  178. +---------+
  179. | file_id |
  180. +---------+
  181. </pre>
  182. @param buf Contains the serialized event.
  183. @param fde An FDE event (see Rotate_event constructor for more info).
  184. */
  185. Delete_file_event(const char *buf, const Format_description_event *fde);
  186. ~Delete_file_event() {}
  187. #ifndef HAVE_MYSYS
  188. // TODO(WL#7684): Implement the method print_event_info and print_long_info
  189. // for
  190. // all the events supported in MySQL Binlog
  191. void print_event_info(std::ostream &) {}
  192. void print_long_info(std::ostream &) {}
  193. #endif
  194. };
  195. /**
  196. @class Append_block_event
  197. This event is created to contain the file data. One LOAD_DATA_INFILE
  198. can have 0 or more instances of this event written to the binary log
  199. depending on the size of the file. If the file to be loaded is greater
  200. than the threshold value, which is roughly 2^17 bytes, the file is
  201. divided into blocks of size equal to the threshold, and each block
  202. is sent across as a separate event.
  203. @section Append_block_event_binary_format Binary Format
  204. The post header contains the following:
  205. <table>
  206. <caption>Post header for Append_block_event</caption>
  207. <tr>
  208. <th>Name</th>
  209. <th>Format</th>
  210. <th>Description</th>
  211. </tr>
  212. <tr>
  213. <td>file_id</td>
  214. <td>32 bit integer</td>
  215. <td>The ID of the file to append the block to</td>
  216. </tr>
  217. </table>
  218. The body of the event contains the raw data to load. The raw data
  219. size is the event size minus the size of all the fixed event parts.
  220. */
  221. class Append_block_event : public Binary_log_event {
  222. protected:
  223. /**
  224. This constructor is used by the MySQL server.
  225. */
  226. Append_block_event(const char *db_arg, unsigned char *block_arg,
  227. unsigned int block_len_arg, uint32_t file_id_arg)
  228. : Binary_log_event(APPEND_BLOCK_EVENT),
  229. block(block_arg),
  230. block_len(block_len_arg),
  231. file_id(file_id_arg),
  232. db(db_arg) {}
  233. Append_block_event(Log_event_type type_arg = APPEND_BLOCK_EVENT)
  234. : Binary_log_event(type_arg) {}
  235. public:
  236. enum Append_block_offset {
  237. /** AB = "Append Block" */
  238. AB_FILE_ID_OFFSET = 0,
  239. AB_DATA_OFFSET = APPEND_BLOCK_HEADER_LEN
  240. };
  241. unsigned char *block;
  242. unsigned int block_len;
  243. uint32_t file_id;
  244. /**
  245. 'db' is filled when the event is created in mysql_load() (the
  246. event needs to have a 'db' member to be well filtered by
  247. binlog-*-db rules). 'db' is not written to the binlog (it's not
  248. used by Append_block_log_event::write()), so it can't be read in
  249. the Append_block_event(const char* buf, int event_len)
  250. constructor. In other words, 'db' is used only for filtering by
  251. binlog-*-db rules. Create_file_event is different: it's 'db'
  252. (which is inherited from Load_event) is written to the binlog
  253. and can be re-read.
  254. */
  255. const char *db;
  256. /**
  257. Appends the buffered data, received as a parameter, to the file being loaded
  258. via LOAD_DATA_FILE.
  259. The buffer layout for fixed data part is as follows:
  260. <pre>
  261. +---------+
  262. | file_id |
  263. +---------+
  264. </pre>
  265. The buffer layout for variable data part is as follows:
  266. <pre>
  267. +-------------------+
  268. | block | block_len |
  269. +-------------------+
  270. </pre>
  271. @param buf Contains the serialized event.
  272. @param fde An FDE event (see Rotate_event constructor for more info).
  273. */
  274. Append_block_event(const char *buf, const Format_description_event *fde);
  275. ~Append_block_event() {}
  276. #ifndef HAVE_MYSYS
  277. // TODO(WL#7684): Implement the method print_event_info and print_long_info
  278. // for
  279. // all the events supported in MySQL Binlog
  280. void print_event_info(std::ostream &) {}
  281. void print_long_info(std::ostream &) {}
  282. #endif
  283. };
  284. /**
  285. @class Begin_load_query_event
  286. Event for the first block of file to be loaded, its only difference from
  287. Append_block event is that this event creates or truncates existing file
  288. before writing data.
  289. @section Begin_load_query_event_binary_format Binary Format
  290. The Post-Header and Body for this event type are empty; it only has
  291. the Common-Header.
  292. */
  293. class Begin_load_query_event : public virtual Append_block_event {
  294. protected:
  295. Begin_load_query_event() : Append_block_event(BEGIN_LOAD_QUERY_EVENT) {}
  296. public:
  297. /**
  298. The buffer layout for fixed data part is as follows:
  299. <pre>
  300. +---------+
  301. | file_id |
  302. +---------+
  303. </pre>
  304. The buffer layout for variable data part is as follows:
  305. <pre>
  306. +-------------------+
  307. | block | block_len |
  308. +-------------------+
  309. </pre>
  310. @param buf Contains the serialized event.
  311. @param fde An FDE event (see Rotate_event constructor for more info).
  312. */
  313. Begin_load_query_event(const char *buf, const Format_description_event *fde);
  314. ~Begin_load_query_event() {}
  315. #ifndef HAVE_MYSYS
  316. // TODO(WL#7684): Implement the method print_event_info and print_long_info
  317. // for
  318. // all the events supported in MySQL Binlog
  319. void print_event_info(std::ostream &) {}
  320. void print_long_info(std::ostream &) {}
  321. #endif
  322. };
  323. } // end namespace binary_log
  324. /**
  325. @} (end of group Replication)
  326. */
  327. #endif /* LOAD_DATA_EVENTS_INCLUDED */