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