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 control_events.h
28 
29   @brief Contains the classes representing events operating in the replication
30   stream properties. Each event is represented as a byte sequence with logical
31   divisions as event header, event specific data and event footer. The header
32   and footer are common to all the events and are represented as two different
33   subclasses.
34 */
35 
36 #ifndef CONTROL_EVENT_INCLUDED
37 #define CONTROL_EVENT_INCLUDED
38 
39 #include "binlog_event.h"
40 #include <list>
41 #include <map>
42 #include <vector>
43 
44 namespace binary_log
45 {
46 /**
47   @class Rotate_event
48 
49   When a binary log file exceeds a size limit, a ROTATE_EVENT is written
50   at the end of the file that points to the next file in the squence.
51   This event is information for the slave to know the name of the next
52   binary log it is going to receive.
53 
54   ROTATE_EVENT is generated locally and written to the binary log
55   on the master. It is written to the relay log on the slave when FLUSH LOGS
56   occurs, and when receiving a ROTATE_EVENT from the master.
57   In the latter case, there will be two rotate events in total originating
58   on different servers.
59 
60   @section Rotate_event_binary_format Binary Format
61 
62   <table>
63   <caption>Post-Header for Rotate_event</caption>
64 
65   <tr>
66     <th>Name</th>
67     <th>Format</th>
68     <th>Description</th>
69   </tr>
70 
71   <tr>
72     <td>position</td>
73     <td>8 byte integer</td>
74     <td>The position within the binary log to rotate to.</td>
75   </tr>
76 
77   </table>
78 
79   The Body has one component:
80 
81   <table>
82   <caption>Body for Rotate_event</caption>
83 
84   <tr>
85     <th>Name</th>
86     <th>Format</th>
87     <th>Description</th>
88   </tr>
89 
90   <tr>
91     <td>new_log_ident</td>
92     <td>variable length string without trailing zero, extending to the
93     end of the event (determined by the length field of the
94     Common-Header)
95     </td>
96     <td>Name of the binlog to rotate to.</td>
97   </tr>
98 
99   </table>
100 */
101 class Rotate_event: public Binary_log_event
102 {
103 public:
104   const char* new_log_ident;
105   size_t ident_len;
106   unsigned int flags;
107   uint64_t pos;
108 
109   enum {
110     /* Values taken by the flag member variable */
111     DUP_NAME= 2, // if constructor should dup the string argument
112     RELAY_LOG= 4 // rotate event for the relay log
113   };
114 
115   enum {
116     /* Rotate event post_header */
117     R_POS_OFFSET= 0,
118     R_IDENT_OFFSET= 8
119   };
120 
121   /**
122     This is the minimal constructor, it will set the type code as ROTATE_EVENT.
123   */
Rotate_event(const char * new_log_ident_arg,size_t ident_len_arg,unsigned int flags_arg,uint64_t pos_arg)124   Rotate_event(const char* new_log_ident_arg, size_t ident_len_arg,
125                unsigned int flags_arg, uint64_t pos_arg)
126     : Binary_log_event(ROTATE_EVENT),
127       new_log_ident(new_log_ident_arg),
128       ident_len(ident_len_arg ? ident_len_arg : strlen(new_log_ident_arg)),
129       flags(flags_arg), pos(pos_arg)
130   {}
131 
132   /**
133     <pre>
134     The buffer layout is as follows:
135     +-----------------------------------------------------------------------+
136     | common_header | post_header | position of the first event | file name |
137     +-----------------------------------------------------------------------+
138     </pre>
139 
140     @param buf                Contains the serialized event.
141     @param length             Length of the serialized event.
142     @param description_event  An FDE event, used to get the
143                               following information
144                               -binlog_version
145                               -server_version
146                               -post_header_len
147                               -common_header_len
148                               The content of this object
149                               depends on the binlog-version currently in use.
150   */
151   Rotate_event(const char* buf, unsigned int event_len,
152                const Format_description_event *description_event);
153 
154 #ifndef HAVE_MYSYS
155   void print_event_info(std::ostream& info);
156   void print_long_info(std::ostream& info);
157 #endif
158 
~Rotate_event()159   ~Rotate_event()
160   {
161     if (flags & DUP_NAME)
162       bapi_free(const_cast<char*>(new_log_ident));
163   }
164 };
165 
166 
167 /**
168   @class Start_event_v3
169 
170   Start_event_v3 is the Start_event of binlog format 3 (MySQL 3.23 and
171   4.x).
172 
173   @section Start_event_v3_binary_format Binary Format
174 
175   Format_description_event derives from Start_event_v3; it is
176   the Start_event of binlog format 4 (MySQL 5.0), that is, the
177   event that describes the other events' Common-Header/Post-Header
178   lengths. This event is sent by MySQL 5.0 whenever it starts sending
179   a new binlog if the requested position is >4 (otherwise if ==4 the
180   event will be sent naturally).
181   The Post-Header has four components:
182 
183   <table>
184   <caption>Post-Header for Start_event_v3</caption>
185 
186   <tr>
187     <th>Name</th>
188     <th>Format</th>
189     <th>Description</th>
190   </tr>
191 
192   <tr>
193     <td>created</td>
194     <td>4 byte unsigned integer</td>
195     <td>The creation timestamp, if non-zero,
196         is the time in seconds when this event was created</td>
197   </tr>
198   <tr>
199     <td>binlog_version</td>
200     <td>2 byte unsigned integer</td>
201     <td>This is 1 in MySQL 3.23 and 3 in MySQL 4.0 and 4.1
202         (In MySQL 5.0 and up, FORMAT_DESCRIPTION_EVENT is
203         used instead of START_EVENT_V3 and for them its 4).</td>
204   </tr>
205   <tr>
206     <td>server_version</td>
207     <td>char array of 50 bytes</td>
208     <td>The MySQL server's version (example: 4.0.14-debug-log),
209         padded with 0x00 bytes on the right</td>
210   </tr>
211   <tr>
212     <td>dont_set_created</td>
213     <td>type bool</td>
214     <td>Set to 1 when you dont want to have created time in the log</td>
215   </table>
216 */
217 
218 class Start_event_v3: public Binary_log_event
219 {
220 public:
221 /*
222     If this event is at the start of the first binary log since server
223     startup 'created' should be the timestamp when the event (and the
224     binary log) was created.  In the other case (i.e. this event is at
225     the start of a binary log created by FLUSH LOGS or automatic
226     rotation), 'created' should be 0.  This "trick" is used by MySQL
227     >=4.0.14 slaves to know whether they must drop stale temporary
228     tables and whether they should abort unfinished transaction.
229 
230     Note that when 'created'!=0, it is always equal to the event's
231     timestamp; indeed Start_event is written only in binlog.cc where
232     the first constructor below is called, in which 'created' is set
233     to 'when'.  So in fact 'created' is a useless variable. When it is
234     0 we can read the actual value from timestamp ('when') and when it
235     is non-zero we can read the same value from timestamp
236     ('when'). Conclusion:
237      - we use timestamp to print when the binlog was created.
238      - we use 'created' only to know if this is a first binlog or not.
239      In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in
240      3.23.57 does not print 'created the_date' if created was zero. This is now
241      fixed.
242   */
243   time_t created;
244   uint16_t binlog_version;
245   char server_version[ST_SERVER_VER_LEN];
246    /*
247     We set this to 1 if we don't want to have the created time in the log,
248     which is the case when we rollover to a new log.
249   */
250   bool dont_set_created;
251 
252 protected:
253   /**
254     Empty ctor of Start_event_v3 called when we call the
255     ctor of FDE which takes binlog_version and server_version as the parameter
256   */
257   explicit Start_event_v3(Log_event_type type_code= START_EVENT_V3);
258 public:
259   /**
260     This event occurs at the beginning of v1 or v3 binary log files.
261     In MySQL 4.0 and 4.1, such events are written only to the first binary log
262     file that mysqld creates after startup. Log files created subsequently
263     (when someone issues a FLUSH LOGS statement or the current binary log file
264     becomes too large) do not contain this event.
265 
266     <pre>
267     The buffer layout for fixed part is as follows:
268     +---------------------------------------------+
269     | binlog_version | server_version | timestamp |
270     +---------------------------------------------+
271     </pre>
272 
273     @param buf                Contains the serialized event.
274     @param description_event  An FDE event, used to get the
275                               following information
276                               -binlog_version
277                               -server_version
278                               -post_header_len
279                               -common_header_len
280                               The content of this object
281                               depends on the binlog-version currently in use.
282   */
283 
284   Start_event_v3(const char* buf, unsigned int event_len,
285                  const Format_description_event* description_event);
286 #ifndef HAVE_MYSYS
287   //TODO(WL#7684): Implement the method print_event_info and print_long_info for
288   //            all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)289   void print_event_info(std::ostream& info) { }
print_long_info(std::ostream & info)290   void print_long_info(std::ostream& info) { }
291 #endif
292 };
293 
294 
295 /**
296   @class Format_description_event
297   For binlog version 4.
298   This event is saved by threads which read it, as they need it for future
299   use (to decode the ordinary events).
300 
301   @section Format_description_event_binary_format Binary Format
302 
303   The Post-Header has six components:
304 
305   <table>
306   <caption>Post-Header for Format_description_event</caption>
307 
308   <tr>
309     <th>Name</th>
310     <th>Format</th>
311     <th>Description</th>
312   </tr>
313 
314   <tr>
315     <td>common_header_len</td>
316     <td>1 byte unsigned integer</td>
317     <td>The length of the event header. This value includes the extra_headers
318         field, so this header length - 19 yields the size
319         of the extra_headers field.</td>
320   </tr>
321   <tr>
322     <td>post_header_len</td>
323     <td>array of type 1 byte unsigned integer</td>
324     <td>The lengths for the fixed data part of each event</td>
325   </tr>
326   <tr>
327     <td>server_version_split</td>
328     <td>unsigned char array</td>
329     <td>Stores the server version of the server
330         and splits them in three parts</td>
331   </tr>
332   <tr>
333     <td>event_type_permutation</td>
334     <td>const array of type 1 byte unsigned integer</td>
335     <td>Provides mapping between the event types of
336         some previous versions > 5.1 GA to current event_types</td>
337   </tr>
338     <tr>
339     <td>number_of_event_types</td>
340     <td>1 byte unsigned integer</td>
341     <td>number of event types present in the server</td>
342   </tr>
343   </table>
344 */
345 class Format_description_event: public virtual Start_event_v3
346 {
347 public:
348   /**
349    The size of the fixed header which _all_ events have
350    (for binlogs written by this version, this is equal to
351    LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT
352    (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN).
353   */
354   uint8_t common_header_len;
355   /*
356    The list of post-headers' lengths followed
357    by the checksum alg decription byte
358   */
359   std::vector<uint8_t> post_header_len;
360   unsigned char server_version_split[ST_SERVER_VER_SPLIT_LEN];
361   /**
362    In some previous version > 5.1 GA event types are assigned
363    different event id numbers than in the present version, so we
364    must map those id's to the our current event id's. This
365    mapping is done using event_type_permutation
366   */
367   const uint8_t *event_type_permutation;
368 
369   /**
370     Format_description_log_event 1st constructor.
371 
372     This constructor can be used to create the event to write to the binary log
373     (when the server starts or when FLUSH LOGS), or to create artificial events
374     to parse binlogs from MySQL 3.23 or 4.x.
375     When in a client, only the 2nd use is possible.
376 
377     @param binlog_ver             the binlog version for which we want to build
378                                   an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
379                                   x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
380                                   old 4.0 (binlog version 2) is not supported;
381                                   it should not be used for replication with
382                                   5.0.
383     @param server_ver             The MySQL server's version.
384   */
385   Format_description_event(uint8_t binlog_ver,
386                            const char* server_ver);
387   /**
388     The layout of the event data part  in  Format_description_event
389     <pre>
390           +=====================================+
391           | event  | binlog_version   19 : 2    | = 4
392           | data   +----------------------------+
393           |        | server_version   21 : 50   |
394           |        +----------------------------+
395           |        | create_timestamp 71 : 4    |
396           |        +----------------------------+
397           |        | header_length    75 : 1    |
398           |        +----------------------------+
399           |        | post-header      76 : n    | = array of n bytes, one byte
400           |        | lengths for all            |   per event type that the
401           |        | event types                |   server knows about
402           +=====================================+
403     </pre>
404     @param buf                Contains the serialized event.
405     @param length             Length of the serialized event.
406     @param description_event  An FDE event, used to get the
407                               following information
408                               -binlog_version
409                               -server_version
410                               -post_header_len
411                               -common_header_len
412                               The content of this object
413                               depends on the binlog-version currently in use.
414     @note The description_event passed to this constructor was created
415           through another constructor of FDE class
416   */
417   Format_description_event(const char* buf, unsigned int event_len,
418                            const Format_description_event *description_event);
419 
420   uint8_t number_of_event_types;
421   unsigned long get_product_version() const;
422   bool is_version_before_checksum() const;
423   void calc_server_version_split();
424 #ifndef HAVE_MYSYS
425   void print_event_info(std::ostream& info);
426   void print_long_info(std::ostream& info);
427 #endif
428   ~Format_description_event();
429 };
430 
431 /**
432   @class Stop_event
433 
434   A stop event is written to the log files under these circumstances:
435   - A master writes the event to the binary log when it shuts down.
436   - A slave writes the event to the relay log when it shuts down or
437     when a RESET SLAVE statement is executed.
438 
439   @section Stop_event_binary_format Binary Format
440 
441   The Post-Header and Body for this event type are empty; it only has
442   the Common-Header.
443 */
444 
445 class Stop_event: public Binary_log_event
446 {
447 public:
448   /**
449     It is the minimal constructor, and all it will do is set the type_code as
450     STOP_EVENT in the header object in Binary_log_event.
451   */
Stop_event()452   Stop_event() : Binary_log_event(STOP_EVENT)
453   {}
454   //buf is advanced in Binary_log_event constructor to point to beginning of
455   //post-header
456 
457   /**
458     A Stop_event is occurs under these circumstances:
459     -  A master writes the event to the binary log when it shuts down
460     -  A slave writes the event to the relay log when it shuts down or when a
461        RESET SLAVE statement is executed
462     @param buf                Contains the serialized event.
463     @param description_event  An FDE event, used to get the
464                               following information
465                               -binlog_version
466                               -server_version
467                               -post_header_len
468                               -common_header_len
469                               The content of this object
470                               depends on the binlog-version currently in use.
471   */
Stop_event(const char * buf,const Format_description_event * description_event)472   Stop_event(const char* buf,
473              const Format_description_event *description_event)
474     :Binary_log_event(&buf, description_event->binlog_version,
475                       description_event->server_version)
476   {}
477 
478 #ifndef HAVE_MYSYS
print_event_info(std::ostream & info)479   void print_event_info(std::ostream& info) {};
480   void print_long_info(std::ostream& info);
481 #endif
482 };
483 
484 
485 /**
486   @class Incident_event
487 
488    Class representing an incident, an occurance out of the ordinary,
489    that happened on the master.
490 
491    The event is used to inform the slave that something out of the
492    ordinary happened on the master that might cause the database to be
493    in an inconsistent state.
494 
495   @section Incident_event_binary_format Binary Format
496 
497    <table id="IncidentFormat">
498    <caption>Incident event format</caption>
499    <tr>
500      <th>Symbol</th>
501      <th>Format</th>
502      <th>Description</th>
503    </tr>
504    <tr>
505      <td>INCIDENT</td>
506      <td align="right">2</td>
507      <td>Incident number as an unsigned integer</td>
508    </tr>
509    <tr>
510      <td>MSGLEN</td>
511      <td align="right">1</td>
512      <td>Message length as an unsigned integer</td>
513    </tr>
514    <tr>
515      <td>MESSAGE</td>
516      <td align="right">MSGLEN</td>
517      <td>The message, if present. Not null terminated.</td>
518    </tr>
519    </table>
520 
521 */
522 class Incident_event: public Binary_log_event
523 {
524 public:
525   /**
526     Enumeration of the incidents that can occur for the server.
527   */
528   enum enum_incident {
529   /** No incident */
530   INCIDENT_NONE = 0,
531   /** There are possibly lost events in the replication stream */
532   INCIDENT_LOST_EVENTS = 1,
533   /** Shall be last event of the enumeration */
534   INCIDENT_COUNT
535   };
536 
get_incident_type()537   enum_incident get_incident_type()
538   {
539     return incident;
540   }
get_message()541   char* get_message()
542   {
543     return message;
544   }
545 
546 
547   /**
548     This will create an Incident_event with an empty message and set the
549     type_code as INCIDENT_EVENT in the header object in Binary_log_event.
550   */
Incident_event(enum_incident incident_arg)551   explicit Incident_event(enum_incident incident_arg)
552     : Binary_log_event(INCIDENT_EVENT),
553       incident(incident_arg),
554       message(NULL),
555       message_length(0)
556   {}
557 
558   /**
559     Constructor of Incident_event
560     The buffer layout is as follows:
561     <pre>
562     +-----------------------------------------------------+
563     | Incident_number | message_length | Incident_message |
564     +-----------------------------------------------------+
565     </pre>
566 
567     Incident number codes are listed in binlog_evnet.h.
568     The only code currently used is INCIDENT_LOST_EVENTS, which indicates that
569     there may be lost events (a "gap") in the replication stream that requires
570     databases to be resynchronized.
571 
572     @param buf                Contains the serialized event.
573     @param length             Length of the serialized event.
574     @param description_event  An FDE event, used to get the
575                               following information
576                               -binlog_version
577                               -server_version
578                               -post_header_len
579                               -common_header_len
580                               The content of this object
581                               depends on the binlog-version currently in use.
582   */
583   Incident_event(const char *buf, unsigned int event_len,
584                  const Format_description_event *description_event);
585 #ifndef HAVE_MYSYS
586   void print_event_info(std::ostream& info);
587   void print_long_info(std::ostream& info);
588 #endif
589 protected:
590   enum_incident incident;
591   char *message;
592   size_t message_length;
593 };
594 
595 
596 /**
597   @class Xid_event
598 
599   An XID event is generated for a commit of a transaction that modifies one or
600   more tables of an XA-capable storage engine.
601 
602   @section Xid_event_binary_format Binary Format
603 
604 The Body has the following component:
605 
606   <table>
607   <caption>Body for Xid_event</caption>
608 
609   <tr>
610     <th>Name</th>
611     <th>Format</th>
612     <th>Description</th>
613   </tr>
614 
615   <tr>
616     <td>xid</td>
617     <td>8 byte unsigned integer</td>
618     <td>The XID transaction number.</td>
619   </tr>
620   </table>
621   The Post-Header and Body for this event type are empty; it only has
622   the common header.
623 */
624 class Xid_event: public Binary_log_event
625 {
626 public:
627   /**
628     The minimal constructor of Xid_event, it initializes the instance variable
629     xid and set the type_code as XID_EVENT in the header object in
630     Binary_log_event
631   */
Xid_event(uint64_t xid_arg)632   explicit Xid_event(uint64_t xid_arg)
633     : Binary_log_event(XID_EVENT),
634       xid(xid_arg)
635   {
636   }
637 
638   /**
639     An XID event is generated for a commit of a transaction that modifies one or
640     more tables of an XA-capable storage engine
641     @param buf                Contains the serialized event.
642     @param description_event  An FDE event, used to get the
643                               following information
644                               -binlog_version
645                               -server_version
646                               -post_header_len
647                               -common_header_len
648                               The content of this object
649                               depends on the binlog-version currently in use.
650   */
651   Xid_event(const char *buf, const Format_description_event *fde);
652   uint64_t xid;
653 #ifndef HAVE_MYSYS
654   void print_event_info(std::ostream& info);
655   void print_long_info(std::ostream& info);
656 #endif
657 };
658 
659 /**
660   @class XA_prepare_event
661 
662   An XA_prepare event is generated for a XA prepared transaction.
663   Like Xid_event it contans XID of the *prepared* transaction.
664 
665   @section XA_prepare_event_binary_format Binary Format
666 
667 The Body has the following component:
668 
669   <table>
670   <caption>Body for XA_prepare_event</caption>
671 
672   <tr>
673     <th>Name</th>
674     <th>Format</th>
675     <th>Description</th>
676   </tr>
677 
678   <tr>
679     <td>my_xid</td>
680     <td>a struct similar to mysql/plugin.h containing three members.</td>
681     <td>serialized XID representation of XA transaction.</td>
682   </tr>
683 
684   <tr>
685     <td>xid</td>
686     <td>a pointer to XID object.</td>
687     <td>a reference to an object for mysql logger.</td>
688   </tr>
689 
690   <tr>
691     <td>one_phase</td>
692     <td>a bool</td>
693     <td>the value specifies the current XA transaction commit method.</td>
694   </tr>
695   </table>
696   The Post-Header and Body for this event type are empty; it only has
697   the common header.
698 */
699 
700 class XA_prepare_event: public Binary_log_event
701 {
702   /*
703     Struct def is copied from $MYSQL/include/mysql/plugin.h,
704     consult there about fine details.
705   */
706   static const int MY_XIDDATASIZE= 128;
707 
708   struct st_mysql_xid {
709     long formatID;
710     long gtrid_length;
711     long bqual_length;
712     char data[MY_XIDDATASIZE];  /* Not \0-terminated */
713   };
714   typedef struct st_mysql_xid MY_XID;
715 
716 protected:
717   /* size of serialization buffer is explained in $MYSQL/sql/xa.h. */
718   static const uint16_t ser_buf_size=
719     8 + 2 * MY_XIDDATASIZE + 4 * sizeof(long) + 1;
720   MY_XID my_xid;
721   void *xid; /* Master side only */
722   bool one_phase;
723 
724 public:
725   /**
726     The minimal constructor of XA_prepare_event, it initializes the
727     instance variable xid and set the type_code as XID_EVENT in the
728     header object in Binary_log_event
729   */
XA_prepare_event(void * xid_arg,bool oph_arg)730   XA_prepare_event(void *xid_arg, bool oph_arg)
731     : Binary_log_event(XA_PREPARE_LOG_EVENT), xid(xid_arg), one_phase(oph_arg)
732   {
733   }
734 
735   /**
736     An XID event is generated for a commit of a transaction that modifies one or
737     more tables of an XA-capable storage engine
738     @param buf    Contains the serialized event.
739     @param fde    An FDE event, used to get the following information
740                      -binlog_version
741                      -server_version
742                      -post_header_len
743                      -common_header_len
744                      The content of this object
745                      depends on the binlog-version currently in use.
746   */
747   XA_prepare_event(const char *buf, const Format_description_event *fde);
748 #ifndef HAVE_MYSYS
749   /*
750     todo: we need to find way how to exploit server's code of
751     serialize_xid()
752   */
print_event_info(std::ostream & info)753   void print_event_info(std::ostream& info) {};
print_long_info(std::ostream & info)754   void print_long_info(std::ostream& info)  {};
755 #endif
756 };
757 
758 
759 /**
760   @class Ignorable_event
761 
762   Base class for ignorable log events. Events deriving from
763   this class can be safely ignored by slaves that cannot
764   recognize them. Newer slaves, will be able to read and
765   handle them. This has been designed to be an open-ended
766   architecture, so adding new derived events shall not harm
767   the old slaves that support ignorable log event mechanism
768   (they will just ignore unrecognized ignorable events).
769 
770   @note The only thing that makes an event ignorable is that it has
771   the LOG_EVENT_IGNORABLE_F flag set.  It is not strictly necessary
772   that ignorable event types derive from Ignorable_event; they may
773   just as well derive from Binary_log_event and Log_event and pass
774   LOG_EVENT_IGNORABLE_F as argument to the Log_event constructor.
775 
776   @section Ignoarble_event_binary_format Binary format
777 
778   The Post-Header and Body for this event type are empty; it only has
779   the Common-Header.
780 */
781 class Ignorable_event: public Binary_log_event
782 {
783 public:
784   //buf is advanced in Binary_log_event constructor to point to beginning of
785   //post-header
786 
787   /**
788     The minimal constructor and all it will do is set the type_code as
789     IGNORABLE_LOG_EVENT in the header object in Binary_log_event.
790   */
791   explicit Ignorable_event(Log_event_type type_arg= IGNORABLE_LOG_EVENT)
Binary_log_event(type_arg)792     : Binary_log_event(type_arg)
793   {}
794   /*
795    @param buf                Contains the serialized event.
796    @param description_event  An FDE event, used to get the
797                              following information
798                              -binlog_version
799                              -server_version
800                              -post_header_len
801                              -common_header_len
802                              The content of this object
803                              depends on the binlog-version currently in use.
804   */
805   Ignorable_event(const char *buf, const Format_description_event *descr_event);
806 #ifndef HAVE_MYSYS
print_event_info(std::ostream & info)807   void print_event_info(std::ostream& info) { }
print_long_info(std::ostream & info)808   void print_long_info(std::ostream& info) { }
809 #endif
810 };
811 
812 
813 /**
814   @struct  gtid_info
815   Structure to hold the members declared in the class Gtid_log_event those
816   member are objects of classes defined in server(rpl_gtid.h). As we can not
817   move all the classes defined there(in rpl_gtid.h) in libbinlogevents so this
818   structure was created, to provide a way to map the decoded value in Gtid_event
819   ctor and the class members defined in rpl_gtid.h, these classes are also the
820   members of Gtid_log_event(subclass of this in server code)
821 
822   The structure contains the following components.
823   <table>
824   <caption>Structure gtid_info</caption>
825 
826   <tr>
827     <th>Name</th>
828     <th>Format</th>
829     <th>Description</th>
830   </tr>
831   <tr>
832     <td>rpl_gtid_sidno</td>
833     <td>4 bytes integer</td>
834     <td>SIDNO (source ID number, first component of GTID)</td>
835   </tr>
836   <tr>
837     <td>rpl_gtid_gno</td>
838     <td>8 bytes integer</td>
839     <td>GNO (group number, second component of GTID)</td>
840   </tr>
841   </table>
842 */
843 struct gtid_info
844 {
845   int32_t  rpl_gtid_sidno;
846   int64_t  rpl_gtid_gno;
847 };
848 
849 /**
850   @struct  Uuid
851 
852   This is a POD.  It has to be a POD because it is a member of
853   Sid_map::Node which is stored in HASH in mysql-server code.
854   The structure contains the following components.
855   <table>
856   <caption>Structure gtid_info</caption>
857 
858   <tr>
859     <th>Name</th>
860     <th>Format</th>
861     <th>Description</th>
862   </tr>
863   <tr>
864     <td>byte</th>
865     <td>unsigned char array</th>
866     <td>This stores the Uuid of the server on which transaction
867         is originated</th>
868   </tr>
869 */
870 
871 struct Uuid
872 {
873 
874    /// Set to all zeros.
clearUuid875   void clear() { memset(bytes, 0, BYTE_LENGTH); }
876    /// Copies the given 16-byte data to this UUID.
copy_fromUuid877   void copy_from(const unsigned char *data)
878   {
879     memcpy(bytes, data, BYTE_LENGTH);
880   }
881   /// Copies the given UUID object to this UUID.
copy_fromUuid882   void copy_from(const Uuid &data) { copy_from((unsigned char *)data.bytes); }
883   /// Copies the given UUID object to this UUID.
copy_toUuid884   void copy_to(unsigned char *data) const { memcpy(data, bytes,
885                                            BYTE_LENGTH); }
886   /// Returns true if this UUID is equal the given UUID.
equalsUuid887   bool equals(const Uuid &other) const
888   { return memcmp(bytes, other.bytes, BYTE_LENGTH) == 0; }
889   /**
890     Return true if parse() would return succeed, but don't actually
891     store the result anywhere.
892   */
893   static bool is_valid(const char *string);
894 
895   /**
896     Stores the UUID represented by a string on the form
897     XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX in this object.
898 
899      @return  0   success.
900              >0   failure
901   */
902   int parse(const char *string);
903   /** The number of bytes in the data of a Uuid. */
904   static const size_t BYTE_LENGTH= 16;
905   /** The data for this Uuid. */
906   unsigned char bytes[BYTE_LENGTH];
907   /**
908     Generates a 36+1 character long representation of this UUID object
909     in the given string buffer.
910 
911     @retval 36 - the length of the resulting string.
912   */
913   size_t to_string(char *buf) const;
914   /// Convert the given binary buffer to a UUID
915   static size_t to_string(const unsigned char* bytes_arg, char *buf);
printUuid916   void print() const
917   {
918     char buf[TEXT_LENGTH + 1];
919     to_string(buf);
920     printf("%s\n", buf);
921   }
922   /// The number of bytes in the textual representation of a Uuid.
923   static const size_t TEXT_LENGTH= 36;
924   /// The number of bits in the data of a Uuid.
925   static const size_t BIT_LENGTH= 128;
926   static const int NUMBER_OF_SECTIONS= 5;
927   static const int bytes_per_section[NUMBER_OF_SECTIONS];
928   static const int hex_to_byte[256];
929 };
930 
931 
932 /**
933   @class Gtid_event
934   GTID stands for Global Transaction IDentifier
935   It is composed of two parts:
936     - SID for Source Identifier, and
937     - GNO for Group Number.
938   The basic idea is to
939      -  Associate an identifier, the Global Transaction IDentifier or GTID,
940         to every transaction.
941      -  When a transaction is copied to a slave, re-executed on the slave,
942         and written to the slave's binary log, the GTID is preserved.
943      -  When a  slave connects to a master, the slave uses GTIDs instead of
944         (file, offset)
945 
946   @section Gtid_event_binary_format Binary Format
947 
948   The Body has seven components:
949 
950   <table>
951   <caption>Body for Gtid_event</caption>
952 
953   <tr>
954     <th>Name</th>
955     <th>Format</th>
956     <th>Description</th>
957   </tr>
958 
959   </tr>
960   <tr>
961     <td>GTID_FLAGS</td>
962     <td>1 byte</td>
963     <td>00000001 = Transaction may have changes logged with SBR.
964         In 5.6, 5.7.0-5.7.18, and 8.0.0-8.0.1, this flag is always set.
965         Starting in 5.7.19 and 8.0.2, this flag is cleared if the transaction
966         only contains row events. It is set if any part of the transaction is
967         written in statement format.</td>
968   </tr>
969   <tr>
970     <td>ENCODED_SID_LENGTH</td>
971     <td>4 bytes static const integer</td>
972     <td>Length of SID in event encoding</td>
973   </tr>
974   <tr>
975     <td>ENCODED_GNO_LENGTH</td>
976     <td>4 bytes static const integer</td>
977     <td>Length of GNO in event encoding.</td>
978   </tr>
979   <tr>
980     <td>last_committed</td>
981     <td>8 byte integer</td>
982     <td>Store the transaction's commit parent sequence_number</td>
983   </tr>
984   <tr>
985     <td>sequence_number</td>
986     <td>8 byte integer</td>
987     <td>The transaction's logical timestamp assigned at prepare phase</td>
988   </tr>
989   </table>
990 
991 */
992 class Gtid_event: public Binary_log_event
993 {
994 public:
995   /*
996     The transaction's logical timestamps used for MTS: see
997     Transaction_ctx::last_committed and
998     Transaction_ctx::sequence_number for details.
999     Note: Transaction_ctx is in the MySQL server code.
1000   */
1001   long long int last_committed;
1002   long long int sequence_number;
1003   /** GTID flags constants */
1004   unsigned static const char FLAG_MAY_HAVE_SBR= 1;
1005   /** Transaction might have changes logged with SBR */
1006   bool may_have_sbr_stmts;
1007   /**
1008     Ctor of Gtid_event
1009 
1010     The layout of the buffer is as follows
1011     +----------+-----------+-- --------+-------+--------------+
1012     |gtid flags|ENCODED SID|ENCODED GNO|TS_TYPE|logical ts(:s)|
1013     +----------+-----------+-----------+-------+--------------+
1014     TS_TYPE is from {G_COMMIT_TS2} singleton set of values
1015 
1016     @param buffer             Contains the serialized event.
1017     @param event_len          Length of the serialized event.
1018     @param description_event  An FDE event, used to get the
1019                               following information
1020                               -binlog_version
1021                               -server_version
1022                               -post_header_len
1023                               -common_header_len
1024                               The content of this object
1025                               depends on the binlog-version currently in use.
1026   */
1027 
1028   Gtid_event(const char *buffer, uint32_t event_len,
1029              const Format_description_event *descr_event);
1030   /**
1031     Constructor.
1032   */
Gtid_event(long long int last_committed_arg,long long int sequence_number_arg,bool may_have_sbr_stmts_arg)1033   explicit Gtid_event(long long int last_committed_arg,
1034                       long long int sequence_number_arg,
1035                       bool may_have_sbr_stmts_arg)
1036     : Binary_log_event(GTID_LOG_EVENT),
1037       last_committed(last_committed_arg),
1038       sequence_number(sequence_number_arg),
1039       may_have_sbr_stmts(may_have_sbr_stmts_arg)
1040   {}
1041 #ifndef HAVE_MYSYS
1042   //TODO(WL#7684): Implement the method print_event_info and print_long_info
1043   //               for all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)1044   void print_event_info(std::ostream& info) { }
print_long_info(std::ostream & info)1045   void print_long_info(std::ostream& info) { }
1046 #endif
1047 protected:
1048   static const int ENCODED_FLAG_LENGTH= 1;
1049   static const int ENCODED_SID_LENGTH= 16;// Uuid::BYTE_LENGTH;
1050   static const int ENCODED_GNO_LENGTH= 8;
1051   /// Length of typecode for logical timestamps.
1052   static const int LOGICAL_TIMESTAMP_TYPECODE_LENGTH= 1;
1053   /// Length of two logical timestamps.
1054   static const int LOGICAL_TIMESTAMP_LENGTH= 16;
1055   // Type code used before the logical timestamps.
1056   static const int LOGICAL_TIMESTAMP_TYPECODE= 2;
1057   gtid_info gtid_info_struct;
1058   Uuid Uuid_parent_struct;
1059 public:
1060   /// Total length of post header
1061   static const int POST_HEADER_LENGTH=
1062     ENCODED_FLAG_LENGTH               +  /* flags */
1063     ENCODED_SID_LENGTH                +  /* SID length */
1064     ENCODED_GNO_LENGTH                +  /* GNO length */
1065     LOGICAL_TIMESTAMP_TYPECODE_LENGTH + /* length of typecode */
1066     LOGICAL_TIMESTAMP_LENGTH;           /* length of two logical timestamps */
1067 
1068   static const int MAX_EVENT_LENGTH=
1069     LOG_EVENT_HEADER_LEN + POST_HEADER_LENGTH;
1070 };
1071 
1072 
1073 /**
1074   @class Previous_gtids_event
1075 
1076   @section Previous_gtids_event_binary_format Binary Format
1077 
1078   The Post-Header for this event type is empty.  The Body has two
1079   components:
1080 
1081   <table>
1082   <caption>Body for Previous_gtids_event</caption>
1083 
1084   <tr>
1085     <th>Name</th>
1086     <th>Format</th>
1087     <th>Description</th>
1088   </tr>
1089 
1090   <tr>
1091     <td>buf</td>
1092     <td>unsigned char array</td>
1093     <td>It contains the Gtids executed in the
1094         last binary log file.</td>
1095   </tr>
1096 
1097   <tr>
1098     <td>buf_size</td>
1099     <td>4 byte integer</td>
1100     <td>Size of the above buffer</td>
1101   </tr>
1102   </table>
1103 */
1104 class Previous_gtids_event : public Binary_log_event
1105 {
1106 public:
1107 
1108   /**
1109     Decodes the gtid_executed in the last binlog file
1110 
1111     <pre>
1112     The buffer layout is as follows
1113     +--------------------------------------------+
1114     | Gtids executed in the last binary log file |
1115     +--------------------------------------------+
1116     </pre>
1117     @param buffer             Contains the serialized event.
1118     @param event_len          Length of the serialized event.
1119     @param description_event  An FDE event, used to get the
1120                               following information
1121                               -binlog_version
1122                               -server_version
1123                               -post_header_len
1124                               -common_header_len
1125                               The content of this object
1126                               depends on the binlog-version currently in use.
1127   */
1128   Previous_gtids_event(const char *buf, unsigned int event_len,
1129                        const Format_description_event *descr_event);
1130   /**
1131     This is the minimal constructor, and set the
1132     type_code as PREVIOUS_GTIDS_LOG_EVENT in the header object in
1133     Binary_log_event
1134   */
Previous_gtids_event()1135   Previous_gtids_event()
1136     : Binary_log_event(PREVIOUS_GTIDS_LOG_EVENT)
1137   {}
1138 #ifndef HAVE_MYSYS
1139   //TODO(WL#7684): Implement the method print_event_info and print_long_info
1140   //               for all the events supported  in  MySQL Binlog
print_event_info(std::ostream & info)1141   void print_event_info(std::ostream& info) { }
print_long_info(std::ostream & info)1142   void print_long_info(std::ostream& info) { }
1143 #endif
1144 protected:
1145   size_t buf_size;
1146   const unsigned char *buf;
1147 };
1148 
1149 /**
1150   @class Transaction_context_event
1151 
1152   This class is used to combine the information of the ongoing transaction
1153   including the write set and other information of the thread executing the
1154   transaction.
1155 
1156   <tr>
1157     <th>Name</th>
1158     <th>Format</th>
1159     <th>Description</th>
1160   </tr>
1161 
1162   <tr>
1163     <td>thread_id</td>
1164     <td>4 byte integer</td>
1165     <td>The identifier for the thread executing the transaction.</td>
1166   </tr>
1167 
1168   <tr>
1169     <td>gtid_specified</td>
1170     <td>bool type variable</td>
1171     <td>Variable to identify whether the Gtid have been specified for the ongoing
1172         transaction or not.
1173     </td>
1174   </tr>
1175 
1176   <tr>
1177     <td>encoded_snapshot_version</td>
1178     <td>unsigned char array</td>
1179     <td>A gtid_set which is used to store the transaction set used for
1180         conflict detection.</td>
1181   </tr>
1182 
1183   <tr>
1184     <td>encoded_snapshot_version_length</td>
1185     <td>4 byte integer</td>
1186     <td>Length of the above char array.</td>
1187   </tr>
1188 
1189   <tr>
1190     <td>write_set</td>
1191     <td>variable length list to store the hash values. </td>
1192     <td>Used to store the hash values of the rows identifier for the rows
1193         which have changed in the ongoing transaction.
1194     </td>
1195   </tr>
1196 
1197   <tr>
1198     <td>read_set</td>
1199     <td>variable length list to store the read set values. Currently empty. </td>
1200     <td>Will be used to store the read set values of the current transaction.</td>
1201   </tr>
1202 
1203 */
1204 class Transaction_context_event : public Binary_log_event
1205 {
1206 public:
1207   /**
1208     Decodes the transaction_context_log_event of the ongoing transaction.
1209 
1210     <pre>
1211     The buffer layout is as follows
1212     </pre>
1213 
1214     @param buf                Contains the serialized event.
1215     @param event_len          Length of the serialized event.
1216     @param descr_event        An FDE event, used to get the
1217                               following information
1218                               -binlog_version
1219                               -server_version
1220                               -post_header_len
1221                               -common_header_len
1222                               The content of this object
1223                               depends on the binlog-version currently in use.
1224   */
1225   Transaction_context_event(const char *buf, unsigned int event_len,
1226                             const Format_description_event *descr_event);
1227 
Transaction_context_event(unsigned int thread_id_arg,bool is_gtid_specified_arg)1228   Transaction_context_event(unsigned int thread_id_arg,
1229                             bool is_gtid_specified_arg)
1230     : Binary_log_event(TRANSACTION_CONTEXT_EVENT),
1231       thread_id(thread_id_arg), gtid_specified(is_gtid_specified_arg)
1232   {}
1233 
1234   virtual ~Transaction_context_event();
1235 
1236   static const char *read_data_set(const char *pos, uint32_t set_len,
1237                                    std::list<const char*> *set,
1238                                    uint32_t remaining_buffer);
1239 
1240   static void clear_set(std::list<const char*> *set);
1241 
1242 #ifndef HAVE_MYSYS
print_event_info(std::ostream & info)1243   void print_event_info(std::ostream& info) { }
print_long_info(std::ostream & info)1244   void print_long_info(std::ostream& info) { }
1245 #endif
1246 
1247 protected:
1248   const char *server_uuid;
1249   uint32_t thread_id;
1250   bool gtid_specified;
1251   const unsigned char *encoded_snapshot_version;
1252   uint32_t encoded_snapshot_version_length;
1253   std::list<const char*> write_set;
1254   std::list<const char*> read_set;
1255 
1256   // The values mentioned on the next class constants is the offset where the
1257   // data that will be copied in the buffer.
1258 
1259   // 1 byte length.
1260   static const int ENCODED_SERVER_UUID_LEN_OFFSET= 0;
1261   // 4 bytes length.
1262   static const int ENCODED_THREAD_ID_OFFSET= 1;
1263   // 1 byte length.
1264   static const int ENCODED_GTID_SPECIFIED_OFFSET= 5;
1265   // 4 bytes length
1266   static const int ENCODED_SNAPSHOT_VERSION_LEN_OFFSET= 6;
1267   // 4 bytes length.
1268   static const int ENCODED_WRITE_SET_ITEMS_OFFSET= 10;
1269   // 4 bytes length.
1270   static const int ENCODED_READ_SET_ITEMS_OFFSET=  14;
1271 
1272   // The values mentioned on the next class's constants is the length of the
1273   // data that will be copied in the buffer.
1274   static const int ENCODED_READ_WRITE_SET_ITEM_LEN= 2;
1275   static const int ENCODED_SNAPSHOT_VERSION_LEN= 2;
1276 };
1277 
1278 /**
1279   @class View_change_event
1280 
1281   This class is used to add view change markers in the binary log when a
1282   member of the group enters or leaves the group.
1283 
1284   <tr>
1285     <th>Name</th>
1286     <th>Format</th>
1287     <th>Description</th>
1288   </tr>
1289 
1290   <tr>
1291     <td>view_id</td>
1292     <td>40 length character array</td>
1293     <td>This is used to store the view id value of the new view change when a node add or
1294         leaves the group.
1295     </td>
1296   </tr>
1297 
1298   <tr>
1299     <td>seq_number</td>
1300     <td>8 bytes integer</td>
1301     <td>Variable to identify the next sequence number to be alloted to the certified transaction.</td>
1302   </tr>
1303 
1304   <tr>
1305     <td>certification_info</td>
1306     <td>variable length map to store the certification data.</td>
1307     <td>Map to store the certification info ie. the hash of write_set and the
1308         snapshot sequence value.
1309     </td>
1310   </tr>
1311 
1312 */
1313 class View_change_event : public Binary_log_event
1314 {
1315 public:
1316   /**
1317     Decodes the view_change_log_event generated incase a server enters or
1318     leaves the group.
1319 
1320     <pre>
1321     The buffer layout is as follows
1322     </pre>
1323 
1324     @param buf                Contains the serialized event.
1325     @param event_len          Length of the serialized event.
1326     @param descr_event        An FDE event, used to get the
1327                               following information
1328                               -binlog_version
1329                               -server_version
1330                               -post_header_len
1331                               -common_header_len
1332                               The content of this object
1333                               depends on the binlog-version currently in use.
1334   */
1335   View_change_event(const char *buf, unsigned int event_len,
1336                     const Format_description_event *descr_event);
1337 
1338   explicit View_change_event(char* raw_view_id);
1339 
1340   virtual ~View_change_event();
1341 
1342   static char *read_data_map(char *pos, uint32_t map_len,
1343                              std::map<std::string, std::string> *map,
1344                              uint32_t consumable);
1345 
1346 #ifndef HAVE_MYSYS
print_event_info(std::ostream & info)1347   void print_event_info(std::ostream& info) { }
print_long_info(std::ostream & info)1348   void print_long_info(std::ostream& info) { }
1349 #endif
1350 
1351 protected:
1352   // The values mentioned on the next class constants is the offset where the
1353   // data that will be copied in the buffer.
1354 
1355   // 40 bytes length.
1356   static const int ENCODED_VIEW_ID_OFFSET= 0;
1357   // 8 bytes length.
1358   static const int ENCODED_SEQ_NUMBER_OFFSET= 40;
1359   // 4 bytes length.
1360   static const int ENCODED_CERT_INFO_SIZE_OFFSET= 48;
1361 
1362 
1363   /*
1364     The layout of the buffer is as follows
1365     +--------------------- -+-------------+----------+
1366     | View Id               | seq number  | map size |
1367     +-----------------------+-------------+----------+
1368    view id (40 bytes) + seq number (8 bytes) + map size (4 bytes)
1369    Sum of the length of the values at the above OFFSETS.
1370   */
1371 
1372   // The values mentioned on the next class constants is the length of the data
1373   // that will be copied in the buffer.
1374 
1375   //Field sizes on serialization
1376   static const int ENCODED_VIEW_ID_MAX_LEN= 40;
1377   static const int ENCODED_CERT_INFO_KEY_SIZE_LEN= 2;
1378   static const int ENCODED_CERT_INFO_VALUE_LEN= 4;
1379 
1380   char view_id[ENCODED_VIEW_ID_MAX_LEN];
1381 
1382   long long int seq_number;
1383 
1384   std::map<std::string, std::string> certification_info;
1385 };
1386 
1387 
1388 /**
1389   @class Heartbeat_event
1390 
1391   Replication event to ensure to slave that master is alive.
1392   The event is originated by master's dump thread and sent straight to
1393   slave without being logged. Slave itself does not store it in relay log
1394   but rather uses a data for immediate checks and throws away the event.
1395 
1396   Two members of the class log_ident and Binary_log_event::log_pos comprise
1397   @see the rpl_event_coordinates instance. The coordinates that a heartbeat
1398   instance carries correspond to the last event master has sent from
1399   its binlog.
1400 
1401   @section Heartbeat_event_binary_format Binary Format
1402 
1403   The Body has one component:
1404 
1405   <table>
1406   <caption>Body for Heartbeat_event</caption>
1407 
1408   <tr>
1409     <th>Name</th>
1410     <th>Format</th>
1411     <th>Description</th>
1412   </tr>
1413 
1414   <tr>
1415     <td>log_ident</td>
1416     <td>variable length string without trailing zero, extending to the
1417     end of the event</td>
1418     <td>Name of the current binlog being written to.</td>
1419   </tr>
1420   </table>
1421 */
1422 class Heartbeat_event: public Binary_log_event
1423 {
1424 public:
1425 
1426   /**
1427     Sent by a master to a slave to let the slave know that the master is
1428     still alive. Events of this type do not appear in the binary or relay logs.
1429     They are generated on a master server by the thread that dumps events and
1430     sent straight to the slave without ever being written to the binary log.
1431 
1432     @param buf                Contains the serialized event.
1433     @param event_len          Length of the serialized event.
1434     @param description_event  An FDE event, used to get the
1435                               following information
1436                               -binlog_version
1437                               -server_version
1438                               -post_header_len
1439                               -common_header_len
1440                               The content of this object
1441                               depends on the binlog-version currently in use.
1442   */
1443   Heartbeat_event(const char* buf, unsigned int event_len,
1444                   const Format_description_event *description_event);
1445 
get_log_ident()1446   const char* get_log_ident() { return log_ident; }
get_ident_len()1447   unsigned int get_ident_len() { return ident_len; }
1448 
1449 protected:
1450   const char* log_ident;
1451   unsigned int ident_len;                      /** filename length */
1452 };
1453 
1454 } // end namespace binary_log
1455 /**
1456   @} (end of group Replication)
1457 */
1458 #endif	/* CONTROL_EVENTS_INCLUDED */
1459