WL#7440: Moving binlog event decoding into separate package

Affects: Server-5.7   —   Status: Complete   —   Priority: Medium

EXECUTIVE SUMMARY
=================
The goal of this worklog is to separate out the  deserialization events in a
MySQL replication stream into the a separate package.

1.BACKGROUND:
In the current implementation of the server:
-Each event is represented by the class Log_event which is the parent class
 and the derived event class.
-Decoding is done partly in the Log_event constructor and in derived 
 event constructor 

2.GOALS:
-Break dependency from the server core and replication framework. 
-Move the code into separate package libbinlogevents.
-Make the package build cleanly, without any dependencies from libraries 
 shipped with the server. 

3.CHALLENGES:
C1: We cannot move the Log_event itself to outside of the server, because we are
    just moving the decoding logic out encoding and apply logic still stays in
    Log_event class.
C2: The header which was decoded inside Log_event constructor is used by both
    libbinlogevents and server, so it should be moved in the library.
C3: Since we want to break source code dependencies from whatever is in the
    server repo (so we can make libbinlogevents self contained), we cannot use
    server header files and also libraries that are shipped only with the
    server, like dbug or mysys.
C4: Separating out the decoding logic from derived event classes, and make these
    classes pretty much POCO(Plain Old C++ Objects)
C5: Support decoding in other data formats like JSON, XML.

4: PROPOSED CHANGES:
-Addressing C1: 
 We have proposed to use inheritance, the basic structure will be same as server
 One parent class Binary_log_event similiar to Log_event, and derived event 
 classes inheriting Binary_log_event.
 These derived event classes (present in libbinlogevents) will contain all
 the data members and member functions which are required for decoding, hence
 making libbinlogevents fully functional, independent of the server.
 And derived event classes in server will inherit these classes.

 Lets understand how the derived event class in server and Binary_log_event
 are dependent or inherited 

              Binary_log_event      
                       |             
                       |              
                      \|/              
        Log_event   Rotate_event      
            |          |             
            |          |              
            |          |              
           \|/        \|/              
          Rotate_log_event 

This structure will be implemented for all the event classes.

-Addressing C2:
 A new class Log_event_header is added in libbinlogevents and a pointer to that
 header is kept in Log_event in server.
 Also it makes more sense to keep the header data separate from event data,
 doing so enables us to do some preprocessing before actully decoding the event.

-Addressing C3:
 To avoid the dependency on server header files and libraries, we have tried to
 replace the occurences and usage of MACROS and methods defined in server by
 standard C  MACROS and methods.
 Example:
 uint*korr methods are replaced by le*toh methods.

-Addressing C4 and C5:
 These will be implemented as separate Wls.
 
The functional and non-functional requirement for this worklog are listed below

FR1.  The decoder implementation should be 100% usable inside and
      outside of the server (i.e., when linked with other
      applications that use the libbinlogevents package). 

FR2.  The error codes and error messages for the decoder SHALL
      remain unchanged when the decoder is used in the server. 


NFR1. There SHALL NOT be any significant performance degradation in
      replication by moving the decoder to another library

NFR2. mysqlbinlog SHALL use the decoder at the new location. 

NFR3. There SHALL NOT be any significant performance degradation in
      mysqlbinlog.

NFR4. The memory footprint/requirements should remain unchanged
There are no  user visible changes.
However, there are changes in the way decoding of events are handled.

An event contains three logical parts, namely the header, the event body and the
event footer. In the current server code, they are represented by abstracting a
common class (Log_event) for the header and footer information, with event
specific information providing implementation of the event body.

The separate package introduces one class for each of the logical divisions:

- Event header : class Log_event_header
- Event body   : Event specific classes providing implementation for the
                 abstract class Binary_log_event
- Event footer : class Log_event_footer

The class, Binary_log_event, is analogous to Log_event in the server (except for
the methods/members used for encoding and applying the event). It is  composed
of Log_event_header and Log_event_footer and inherited by event classes. Each
event class decodes an event of specific type(s) in the constructor. The event
type is known from the header of the event. The event classes in the server call
these constructors to decode the event.


The inheritance structure is affected as follows:

We will take two classes for explaining the changes
1) Rotate_log_event
2) Format_description_log_event


+==============================================================================+| 
EARLIER                              |                 NOW                  |
|-------------------------------------------------------------------------------
|1) Rotate_log_event                    |                                      |
|                                       |                Binary_log_event      |
|                                       |                      /|\             |
|         Log_event                     |                       |              |
|           /|\                         |                       |              |
|            |                          |        Log_event   Rotate_event      |
|            |                          |           /|\        /|\             |
|     Rotate_log_event                  |            |          |              |
|                                       |            |          |              |
|                                       |            |          |              |
|                                       |         Rotate_log_event             |
|                                       |                                      |
|                                       |                                      |
|=======================================|=======================================
|2) Format_description_log_event        |                                      |
|                                       |             Binary_log_event         |
|                                       |                   /|\                |
|                                       |                    |                 |
|        Log_event                      |                    |                 |
|           /|\                         | Log_event     Start_event_v3         |
|            |                          |   /|\      (1)    / \   (2)          |
|            |                          |    |     <<vir>> /   \ <<vir>>       |
|    Start_log_event_v3                 |    |            /     \              |
|           /|\                         |    |           /       \             |
|            |                          |Start_log_event_v3   Format_desc_event|
|            |                          |                \       /             |
|  Format_description_log_event         |                 \     /              |
|                                       |                  \   /               |
|                                       |                  _\ /_               |
|                                       |         Format_description_log_event |
|                                       |                                      |
+==============================================================================+


The link (1) and (2) shown above in the class diagram for
Format_description_log_event on the right side, are virtual.

class Start_log_event_v3: public Log_event, public virtual Start_event_v3
{
.......
.......
};

class Format_description_event: public virtual Start_event_v3
{
.....
.....
};

Virtual inheritance is introduced in order to avoid the Diamond problem.
If virtual inheritance is not used object of Format_description_log_event will
see two copies of all the members present in Binary_log_event



BUILDING BLOCKS
===============
All the events are part of the namespace binary_log in binlog-api package.
The design for binlog-api represents events following a hierarchy.
On the top is an abstract class, Binary_log_event.
Binary_log_event used composition to represent one whole event, containing an
object of header and footer.


In binlog-api:
--------------

  class Binary_log_event  
  {
   // Static enumerations, constants common to all events
   // event constructors

     Log_event_header* header() { return &m_header; }
     Log_event_footer* footer() { return &m_footer; }
   private:
     Log_event_header m_header;
     Log_event_footer m_footer;
  };

  - Objects of the header and the footer is held in the Binary_log_event class,
and a pointer to this object is held in Log_event.

 An example: 
  class Rotate_event : public Binary_log_event
  {
    public:
    const char* new_log_ident;
    unsigned int ident_len; 
    unsinged int flags;
    uint64_t pos;

   binary_log::Rotate_event(cont char* buf, const FDE des_ev)
   : Binary_log_event(buf, des_ev)        // This call decodes the header and 
                                          // footer information
   {
   public:
      ...   // decoding event specific data
   };


In SERVER:
----------

  class Log_event
  {
    public:
    ...
    /*
      common_header and common_footer are pointers to m_header and m_footer
      respectively which are defined in the class Binary_log_event.
      There scope should be the same as that of Log_event.
      m_header and m_footer might exist even after common_header and 
      common_footer is destroyed.
    */
    Log_event_header *common_header;
    Log_event_footer *common_footer;

    Log_event(Log_event_header *header, Log_event_footer *footer)
    : common_header(header), common_footer(footer)
    { }
  };

An example:

  class Rotate_log_event : public binary_log::Rotate_event, public Log_event
  {
     public:
       ...      // event specific member vars for encoding and applying the   
                // event
     Rotate_log_event(const char* buf, const FDE des_ev)
     : Rotate_event(buf, des_ev),     // The header and footer are 
                                      // initialized in this constructor call,
                                      // as well as event data

     Log_event(this->header(), this->footer())    
     {
        if (is_valid())
         return;
        return 1;
     }
  };



RATIONALE
----------
The rationale behind separating out the header and checksum from the event data
is the following:

- The structure of the event header and the footer is common to all the events.
It is logically reasonable to separate them out from event data.

-  In order to move event decoding into Binlog-api, it is designed to have the
event classes in the server to   inherit the event classes in binlogapi. The
inheritance structure is as follows:

                  +---------------------+
                  |  Binary_log_event   |
                  +---------------------+  
                             ^       
                             |                                      
                             |                            
                             |                                        
                             |                                        
             +-----------------------------------+              +------------+
             | binary_log::Individual event class|              | Log_event  |
             +-----------------------------------+              +------------+
                             ^                                        ^
                             |                                        |
                             |                                        |
                             |                                        |
                             |    +--------------------------------+  |
                             +----| Server::Individual event class |--+
                                  +--------------------------------+


- Before decoding any event, and constructing an object of a specific event
type, the event header is created and the event checksum is tested. This
requires the header fields and the checksum algorithm descriptor to  be visible
in the parent classes, Binary_log_event and Log_event. 

However, as there is no linking b/w both the two parent classes
(Binary_log_event and Log_event)   we require keeping the header and the
checksum_alg descriptor into separate classes visible to both.


INTRODUCTION
============

A. Create an object for representing the header part of an event buffer

     /**
       @class Log_event_header
    
        All event have a common general structure consisting of an event 
        header followed by event data.
        +============+
        |event header|
        +============+
        | event data |
        +============+
         
        The fields present in header is common among all the events, so it 
        makes more sense to have all those
        fields inside a single class. The member variables declared here were 
        previously a part of Log_event class
        they have been removed from there. These variables are initialized in 
        the constructor for Log_event_header
     */
    class Log_event_header  
    { 
    public:
     /*
      Timestamp on the master(for debugging and replication of NOW()/TIMESTAMP).
      It is important for queries and LOAD DATA INFILE. This is set at the 
      event's creation time, except for Query and Load (and other events) 
      events where this is set at the query's execution time, which guarantees 
      good replication (otherwise, we could have a query and its event with 
      different timestamps).                
     */
     struct timeval when;
                                                                                
     /**
       Event type extracted from the header. In the server, it is decoded
       by read_log_event(), but adding here for complete decoding.  
     */
     Log_event_type  type_code;
                                                                                
     /*
      The server id read from the Binlog.   
     */
     unsigned int unmasked_server_id;
                                                                                
     /* Length of an event, which will be written by write() function */
     unsigned long data_written;
                                                                                
     /*
      The offset in the log where this event originally appeared (it is
      preserved in relay logs, making SHOW SLAVE STATUS able to print
      coordinates of the event in the master's binlog). Note: when a
      transaction is written by the master to its binlog (wrapped in
      BEGIN/COMMIT) the log_pos of all the queries it contains is the
      one of the BEGIN (this way, when one does SHOW SLAVE STATUS it
      sees the offset of the BEGIN, which is logical as rollback may
      occur), except the COMMIT query which has its real offset.
     */
     unsigned long long log_pos;        
                                                                                
     /*
      16 or less flags depending on the version of the binary log.   
      See the definitions above for LOG_EVENT_TIME_F, 
      LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_THREAD_SPECIFIC_F, and 
      LOG_EVENT_SUPPRESS_USE_F for notes.
     */
     uint16_t flags;     
  
     /*
      The following type definition is to be used whenever data is placed  
      and manipulated in a common buffer. Use this typedef for buffers 
      that contain data containing binary and character data.  
     */
     typedef unsigned char Byte; 
                                                                                
     Log_event_header(Log_event_type type_code_arg= ENUM_END_EVENT)
     : type_code(type_code_arg), log_pos(0), flags(0)
     {
       when.tv_sec= 0;
       when.tv_usec= 0;
     }
     Log_event_header(const char* buf, uint16_t binlog_version);

     ~Log_event_header() {}
   };                                    

 B. Create an object for the footer of an event
    
    /**
     @class Log_event_footer

     The footer, in the current version of the MySQL server, only contains
     the checksum algorithm descriptor. The descriptor is contained in the
     FDE of the binary log. This is common for all the events contained in
     that binary log, and defines the algorithm used to checksum
     the events contained in the binary log.

     @note checksum *value* is not stored in the event. On master's side, it
           is calculated before writing into the binary log, depending on the
           updated event data. On the slave, the checksum value is retrieved
           from a particular offset and checked for corruption, by computing
           a new value. It is not required after that. Therefore, it is not
           required to store the value in the instance as a class member.
    */
    class Log_event_footer
    {
    public:

      enum_binlog_checksum_alg
      static get_checksum_alg(const char* buf, unsigned long len);

      static bool event_checksum_test(unsigned char* buf,
                                      unsigned long event_len,
                                      enum_binlog_checksum_alg alg);

      /* Constructors */
      Log_event_footer()
     : checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
     {
     }

     Log_event_footer(enum_binlog_checksum_alg checksum_alg_arg)
     : checksum_alg(checksum_alg_arg)
     {
     }

     /*
      Master side:
      The value is set by caller of FD(Format Description) constructor
      In the FD case it's propagated into the last byte
      of post_header_len[].
      Slave side:
      On the slave side the value is assigned from post_header_len[last]
      of the last seen FD event.
    */
    enum_binlog_checksum_alg checksum_alg;
  };

 C. The member variables present in  the above two classes (A),(B) were 
    previously the instance variables of Log_event class.
    We have moved them out of the Log_event_class.
    Now the question arises how are we going to access those variables, so for
    that we have two instance variables in the class Log_event
                                                                          
    /* 
     Log_event_header class contains all the variables which are there
     in the header of the event buffer.
    */
    Log_event_header *common_header;
    /* 
     Log_event_footer contains the methods and variables needed for
     checksum verification
    */
    Log_event_footer *common_footer;
    
    These object pointers will be initialized in the Log_event constructors,
    below is an example of that.

    Log_event::Log_event(Log_event_header* header, Log_event_footer *footer,
                         enum_event_cache_type cache_type_arg,
                         enum_event_logging_type logging_type_arg)
    : temp_buf(0), exec_time(0), event_cache_type(cache_type_arg),
      event_logging_type(logging_type_arg), crc(0), common_header(header),
      common_footer(footer), thd(0), is_valid(false)
    {
      server_id= ::server_id;
      common_header->unmasked_server_id= server_id;
    }

D. The parent class for all the events classes in binlog_event.h, it plays the 
   same role which Log_event plays in log_event.h
 
    /** 
     @class Binary_log_event
   
      This is the base class for all other event classes, 
      There are two virtual method 
          -print_event_info
          -print_long_info
      These methods will not be used inside server but will be used in the   
      independent version of  BAPI, they are used to print the information 
      inside an event.
      In the future mysqlbinlog might use these methods for printing the event 
      info.
    */
    class Binary_log_event
    {
    public:

      /*
       The number of types we handle in Format_description_event (UNKNOWN_EVENT
       is not to be handled, it does not exist in binlogs, it does not have a
       format).
      */
      static const int LOG_EVENT_TYPES= (ENUM_END_EVENT - 2);

      /**
       The lengths for the fixed data part of each event.
       This is an enum that provides post-header lengths for all events.
      */
      enum enum_post_header_length{
      // where 3.23, 4.x and 5.0 agree
      QUERY_HEADER_MINIMAL_LEN= (4 + 4 + 1 + 2),
      // where 5.0 differs: 2 for length of N-bytes vars.
      QUERY_HEADER_LEN=(QUERY_HEADER_MINIMAL_LEN + 2),
      STOP_HEADER_LEN= 0,
      LOAD_HEADER_LEN= (4 + 4 + 4 + 1 +1 + 4),
      START_V3_HEADER_LEN= (2 + ST_SERVER_VER_LEN + 4),
      // this is FROZEN (the Rotate post-header is frozen)
      ROTATE_HEADER_LEN= 8,
      INTVAR_HEADER_LEN= 0,
      CREATE_FILE_HEADER_LEN= 4,
      APPEND_BLOCK_HEADER_LEN= 4,
      EXEC_LOAD_HEADER_LEN= 4,
      DELETE_FILE_HEADER_LEN= 4,
      NEW_LOAD_HEADER_LEN= LOAD_HEADER_LEN,
      RAND_HEADER_LEN= 0,
      USER_VAR_HEADER_LEN= 0,
      FORMAT_DESCRIPTION_HEADER_LEN= (START_V3_HEADER_LEN + 1 +\
                                      LOG_EVENT_TYPES),
      XID_HEADER_LEN= 0,
      BEGIN_LOAD_QUERY_HEADER_LEN= APPEND_BLOCK_HEADER_LEN,
      ROWS_HEADER_LEN_V1= 8,
      TABLE_MAP_HEADER_LEN= 8,
      EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN= (4 + 4 + 4 + 1),
      EXECUTE_LOAD_QUERY_HEADER_LEN= (QUERY_HEADER_LEN +\
                                      EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN),
      INCIDENT_HEADER_LEN= 2,
      HEARTBEAT_HEADER_LEN= 0,
      IGNORABLE_HEADER_LEN= 0,
      ROWS_HEADER_LEN_V2= 10
    }; // end enum_post_header_length
   protected:
    Binary_log_event(Log_event_type type_code= ENUM_END_EVENT)
    : m_header(type_code)
    {
      /*
       We set the type code to ENUM_END_EVENT so that the decoder
       asserts if event type has not been modified by the sub classes.
      */
    }

    Binary_log_event(const char **buf, uint16_t binlog_version,
                   const char *server_version);
   public:
    /**
     Returns short information about the event
    */
    virtual void print_event_info(std::ostream& info);
    /**
     Returns detailed information about the event
    */
    virtual void print_long_info(std::ostream& info);
    virtual ~Binary_log_event() = 0;

    /**
     Helper method
    */
    enum Log_event_type get_event_type() const
    {
      return (enum Log_event_type) m_header.type_code;
    }

    /**
     Return a pointer to the header of the log event
    */
    Log_event_header *header() const
    {
      return const_cast<Log_event_header*>(&m_header);
    }
    /**
     Return a pointer to the footer of the log event
    */
    Log_event_footer *footer() const
    {
      return const_cast<Log_event_footer*>(&m_footer);
    }

   private:
    Log_event_header m_header;
    Log_event_footer m_footer;
  };

 E. There are few new wrapper in-line methods added for memory allocation and 
    deallocation, listed below
    
    1)
     /*
      This is a wrapper function, and returns a pointer to a new string which is
      a duplicate of the input string. The terminating Null character is added.

      If compiled with MySQL server,the strndup function from the mysys library 
      is called, which allow instrumenting memory allocated. Else, the standard
      string function is called.

      @param destination The string to be duplicated
      @param n           The number of bytes to be copied

      @return            The duplicated string, or 
                         NULL if insufficient memory was available.
     */
     inline const char* bapi_strndup(const char *destination, size_t n)
  
    2)
     /*
      This is a wrapper function, and returns a pointer to a new memory with the
      contents copied from the input memory pointer, upto a given length

      @param source Pointer to the buffer from which data is to be copied
      @param len    Length upto which the source should be copied

      @return       dest pointer to a new memory if allocation was successful
                    NULL otherwise
     */
     inline const void* bapi_memdup(const void* source, size_t len)
  
    3)
     /*
      This is a wrapper function inorder to  allocate memory from the heap
      in the binlogevent library.

      If compiled with the MySQL server, and memory is allocated using memory
      allocating methods from the mysys library, my_malloc is called. Otherwise,
      the standard malloc() is called from the function.

      @param  size  Size of the memory to be allocated.
      @return       Void pointer to the allocated chunk of memory
     */
      inline void * bapi_malloc(size_t size, enum PSI_memory_key_to_int 
                                key_to_int= MEMORY_LOG_EVENT, int flags= 0)
    
     4)
      /*
        This is a wrapper function inorder to free the memory allocated from 
        the heap in the binlogevent library.

        If compiled with the MySQL server, and memory is allocated using memory
        allocating methods from the mysys library, my_free is called. Otherwise,
        the standard free() is called from the function.

        @param  ptr   Pointer to the memory which is to be freed.
      */
      inline void bapi_free(void* ptr)


F. When moving the code from server to libbinlogevent we have changed/added few 
   member variables and methods,
   below is a list of such changes.


   1) QUERY_EVENT
      ===========             
      w.r.t user and host
      - user and host are defined as LEX_STRING in the Query_log-event, changed 
        them to std::sring

      w.r.t data_buf in the Query_log_event
      - Since data_buf buffer is not needed for/by the decoder, data_buf is to 
        be kept a part of the server i.e Query_log_event instead of   
        binary_log::Query_event.
      - The const char pointers to this buf has been replaced by std::string in 
        the bapi::Query_event, and are declared as private members.
      - Since the data_buf cannot be done away with, it is allocated in 
        Query_log_event instead of binary_log::Query_event.
      - Another set of const char* pointers are members of Query_log_event on 
        the server side, which would point to this data_buffer.
      - A function in the libinlogevent class Query_event is added which would 
        take a pointer to this data_buf, and fill the possible fields in the 
        buffer  
        (int Query_event::fill_data_buf(Binary_log_event::Byte* buf).  
        This method is called from within the Query_log_event constructor in 
        the server.
      - Query_event::fill_data_buf will use the strings it has decoded in order 
        to fill the buffer in the format required by the handler.
        Once the data_buf is filled, we set the pointers in the Query_log_event 
        at the particular offsets to this data_buf.
        We then use these pointers inside the server code for referring to the 
        catalog, time_zone_str, query, db, user or host 
      - For other users of binlog api (other than MySQL server), getters and 
        setters are defined for the string data members.

   2) INCIDENT_EVENT
      ==============
      w.r.t member variable m_message
      - The variable m_message which is of type LEX_STRING is divided into two 
        variables
           - char * m_message         // storing the message
           - size_t m_message_length //storing the length of the message.
                 
   3) LOAD_EVENT
      ==========
      w.r.t structures sql_ex_data_info and old_sql_ex     
      - Structure sql_ex_data_info and old_sql_ex  added to libbinlogevent 
        these structures hold the sub clause information for a LOAD_DATA_INFILE 
        query.
      - Modified the structure sql_ex_info in log_event.h to contain an object 
        of binary_log::sql_ex_data_info.
                          
   4) We have  replaced the usage of  uin*korr macros by corresponding le*toh 
      macros, to remove the dependency on mysys 

G. For all the event classes in log_event.h, there is a corresponding class in 
   binlog_event.h, 
   for example: in log_event.h we have Rotate_log_event in 
                binlog_event.h we have Rotate_event.
   
 
    Below is a diagram to show the flow of execution inside the method 
    dump_remote_log_entries in mysqlbinlog, when we are reading from remote 
    server.

         +========================================+
         |         EARLIER IMPLEMENTATION         |   
         +========================================+
  
          dump_remote_log_entries(mysqlbinlog.cc)
                            |
                            |
       read_log_event(const char *buf, ..) (log_event.cc)
                            |
                            |
       case RAND_EVENT
       ev = new Rand_log_event(buf, &des_ev); (log_event.cc)
                             |
                             |
       Rand_log_event(const char *buf, FDE *fde) (log_event.cc)


        
        +========================================+
        |         PROPOSED IMPLEMENTATION        |   
        +========================================+
  
           dump_remote_log_entries(mysqlbinlog.cc)
                             |
                             |
        read_log_event(const char *buf, ..) (log_event.cc)
                             |
                             |
        case RAND_EVENT
        ev = new Rand_log_event(buf, &des_ev); (log_event.cc)
                             |
                             |
       Rand_log_event(const char *buf, FDE *fde) (log_event.cc)
                             |
                             |
   +------------------------------------------------------------------------+
   |Rand_event(const char *buf, FDE *fde) (binlog_event.cc inlibbinlogevent)|
   +------------------------------------------------------------------------+



Below mentioned is a list of files which
are affected by this worklog, pointing the major and minor changes in each.

Files changed in the server code:
=================================
Added: libbinlogevents/*

Deleted: sql/table_id.h

Modified:

LOG_EVENT.CC / LOG_EVENT_OLD.CC
LOG_EVENT.H / LOG_EVENT_OLD.H
Moved decoding of events into binlog_event.h/.cpp, changed class inheritance
structure.

CLIENT/MYSQLBINLOG.CC
Major change:
None
Minor change:
- The following variables were present in class Log_event before, now they are
moved to the class Log_event_header.
   struct timeval when; 
   uint32 server_id; 
   ulong data_written;   
   uint16 flags;  
   my_off_t log_pos;    

  Changes in this file are a result of the above:
   -  if (((my_time_t)(ev->when.tv_sec) >= start_datetime))
   +  if ((my_time_t) (ev->common_header->when.tv_sec) >= start_datetime)).

   Similarly for type_code
   -  switch (ev->get_type_code())
   +  switch (ev->common_header->type_code)

-  Added namespace resoluter for using elements of enum Log_event_type, since
the enum is now a static member of class Binary_log_event

       if (uint4korr(buf + EVENT_LEN_OFFSET) <                                
    -     (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN))
    +     (LOG_EVENT_MINIMAL_HEADER_LEN + Binary_log_event::START_V3_HEADER_LEN))


SQL/BINLOG.CC
Major change:
None
Minor change:
 - In the method  MYSQL_BIN_LOG::open_binlog,  replaced nested ternary operators
used to initialize checksum_alg for the FDE, by if-else struct

 - Changes reflect moving variables when, type_code, flags, data_written, that
were present in class Log_event before,
   now they are moved to the class Log_event_header.

 - Changes reflect moving checksum_alg into class Log_event_footer. The data
type is changed from uint8 to enum.

   -  s->checksum_alg= relay_log_checksum_alg;
   +  (s.common_footer)->checksum_alg= relay_log_checksum_alg;

   -   relay_log_checksum_alg : binlog_checksum_options;                  
   +   relay_log_checksum_alg :
static_cast<enum_binlog_checksum_alg>(binlog_checksum_options);

 - Added namespace resoluter for using elements of enum Log_event_type.

SQL/RPL_SLAVE.CC
Major change:
None
Minor change:

- Changes reflect moving checksum_alg into class Log_event_footer. The data type
is changed from uint8 to enum.
- Changes reflect moving variables when, type_code, log_pos, that were present
in class Log_event before,
   now they are moved to the class Log_event_header.

- before calling event_checksum_test, we set the dbug variable
'simulate_checksum_test_failure', defined in libbinlogevents

 <   if (event_checksum_test((uchar *) buf, event_len, checksum_alg))           
 ---                                                                            
 >   Format_description_event *des_ev= NULL;                                    
 >   binary_log_debug::debug_checksum_test=                                     
 >                DBUG_EVALUATE_IF("simulate_checksum_test_failure", true, false);
 >   if (Log_event_footer::event_checksum_test((uchar *) buf,                   
 >                                             event_len, checksum_alg))        

- The method  used to calculate a long checksum for a memory block is
libbinloevents/include/binlog_event.h:checksum_crc32() instead of mysys::my_checksum

 <       ha_checksum rot_crc= my_checksum(0L, NULL, 0);                         
 ---                                                                            
 >       ha_checksum rot_crc= checksum_crc32(0L, NULL, 0);                      



SQL/RPL_RLI.CC
Major change:
None
Minor change:
- Changes reflect moving variables type_code, log_pos, data_written that were
present in class Log_event before,
   now they are moved to the class Log_event_header.

SQL/RPL_UTILITY.CC
Major change:
- The following method definitions  are moved:

1. max_display_length_for_field, which computes  the maximum display length of a
field moved to libbinlogevents/src/value.cpp

< static uint32                                                                
< max_display_length_for_field(enum_field_types sql_type, unsigned int metadata)
---
>  uint32_t                                                                       
> max_display_length_for_field(enum_field_types sql_type, unsigned int metadata);
 
2. uint_max, which computes Max value for an unsigned integer of 'bits' bits  is
moved to libbinlogevents/src/value.cpp

< static uint32 uint_max(int bits)    
---
> static uint32_t uint_max(int bits)                                        

3.  event_checksum_test, which tests the checksum algorithm used for the binary
log to libbinlogevents/src/binlog_event.cpp

< bool event_checksum_test(uchar *event_buf, ulong event_len, uint8 alg)       
---
> static Log_event_footer::bool event_checksum_test(uchar *event_buf, ulong
event_len, uint8 alg)       

Minor Change:
- The method  used to calculate a long checksum for a memory block is
libbinloevents/include/binlog_event.h:checksum_crc32() instead of mysys::my_checksum

SQL/TABLE_ID.H
Major Change:

 - moved to libbinlogevents/include with the same name
 - Removed the method is_invalid() from class Table_id

SQL/RPL_MTS_SUBMODE.CC
Major change:
None
Minor change:
-Changes reflect moving variables type_code that was present in class Log_event
before,    now they are moved to the class Log_event_header.

SQL/RPL_RLI.CC
Major change:
None
Minor change:

- Changes reflect moving variables when, type_code, log_pos, data_written that
were present in class Log_event before,
   now they are moved to the class Log_event_header.

SQL/RPL_RLI_PDB.CC
Major change:
None

Minor change:
- Changes reflect moving variables when, type_code, log_pos, data_written that
were present in class Log_event before,
   now they are moved to the class Log_event_header.


SQL/SQL_BINLOG.CC
Major change:
None
Minor change:
-Changes reflect moving variables type_code that was present in class Log_event
before,
   now they are moved to the class Log_event_header.

SQL/MYSQLD.CC
Major change:
None
Minor change:
-Changes reflect moving variables type_code that was present in class Log_event
before,
   now they are moved to the class Log_event_header.

SQL/MYSQLD.H
Major change:
None
Minor change:
removed extern declaration for key_memory_log_event

SQL/RPL_BINLOG_SENDER.CC
Major change:
None
Minor change:
- Changes reflect moving checksum_alg into class Log_event_footer. The data type
is changed from uint8 to enum.
- The method  used to calculate a long checksum for a memory block is
libbinloevents/include/binlog_event.h:checksum_crc32() instead of mysys::my_checksum
-  Added namespace resoluter for using elements of enum Log_event_type,
  since the enum is now a static member of class Binary_log_event

SQL/RPL_INJECTOR.H
Major change:
None
Minor change:
- Added the header file binlog_event.h.  (Required for the enumeration Incident
defined in the header)

RPL_CONSTANTS.H
Major change:
- Removed the enumeration Incident as it is added in binlog_event.h
- Moved pre processor symbols to libbinlogevents/include/rows_event.h
   EXTRA_ROW_INFO_FORMAT_OFFSET
   EXTRA_ROW_INFO_LEN_OFFSET
   EXTRA_ROW_INFO_HDR_BYTES
   EXTRA_ROW_INFO_MAX_PAYLOAD

SQL/RPL_GTID.H
Major change:
  Removed enum_remove_gtid from here to binlog_event.h, being used while
decoding of Gtid_event

INCLUDE/MYSQL_COM.H
Major change:
None
Minor change:
Added define guards for NAME_LEN, for it is defined in libbinlogevents, if it is
compiled independent of the server.
                                                                      
> #ifndef NAME_LEN                                                             
---                                                                        
> #endif                                                                       

SQL/SQL_PRIV.H
Major change:
Moved template definitions 
  valid_buffer_range (which checks how many bytes are available on buffer) and
  available_buffer     (which checks if jump value is within buffer limits)
  to binlog_event.h, since they are used only while decoding RAND_EVENT


SQL/SQL_TABLE.CC
Major change:
None
Minor change:
- The method  used to calculate a long checksum for a memory block is
libbinloevents/include/binlog_event.h:checksum_crc32() instead of
mysys/checksum.c:my_checksum

SQL/RPL_MI.H, SQL/RPL_BINLOG_SENDER.H
Major change:
None
Minor change:
- Changes reflect moving checksum_alg into class Log_event_footer. The data type
is changed from uint8 to enum.

<   uint8 m_event_checksum_alg;                                                
<   uint8 m_slave_checksum_alg;                                                
---                                                                            
>   enum_binlog_checksum_alg m_event_checksum_alg;                             
>   enum_binlog_checksum_alg m_slave_checksum_alg;                             


SQL/BINLOG.H
Major change:
None
Minor change:
- Changes reflect moving checksum_alg into class Log_event_footer. The data type
is changed from uint8 to enum.
- size_t instead of uint for storing the return value of strlen


For more details please see the attachement LLD_7440