summaryrefslogtreecommitdiff
path: root/sql/log_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log_event.h')
-rw-r--r--sql/log_event.h703
1 files changed, 608 insertions, 95 deletions
diff --git a/sql/log_event.h b/sql/log_event.h
index c181b5ce4c6..1a7ffd9e829 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1,4 +1,5 @@
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2014, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -48,6 +49,8 @@
#include "sql_class.h" /* THD */
#endif
+#include "rpl_gtid.h"
+
/* Forward declarations */
class String;
@@ -251,13 +254,18 @@ struct sql_ex_info
#define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
#define XID_HEADER_LEN 0
#define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN
-#define ROWS_HEADER_LEN 8
+#define ROWS_HEADER_LEN_V1 8
#define TABLE_MAP_HEADER_LEN 8
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
#define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
#define INCIDENT_HEADER_LEN 2
#define HEARTBEAT_HEADER_LEN 0
+#define IGNORABLE_HEADER_LEN 0
+#define ROWS_HEADER_LEN_V2 10
#define ANNOTATE_ROWS_HEADER_LEN 0
+#define BINLOG_CHECKPOINT_HEADER_LEN 4
+#define GTID_HEADER_LEN 19
+#define GTID_LIST_HEADER_LEN 4
/*
Max number of possible extra bytes in a replication event compared to a
@@ -288,7 +296,7 @@ struct sql_ex_info
to the slave. It is used to increase the thd(max_allowed) for both the
DUMP thread on the master and the SQL/IO thread on the slave.
*/
-#define MAX_MAX_ALLOWED_PACKET 1024*1024*1024
+#define MAX_MAX_ALLOWED_PACKET (1024*1024*1024)
/*
Event header offsets;
@@ -409,6 +417,9 @@ struct sql_ex_info
/* RW = "RoWs" */
#define RW_MAPID_OFFSET 0
#define RW_FLAGS_OFFSET 6
+#define RW_VHLEN_OFFSET 8
+#define RW_V_TAG_LEN 1
+#define RW_V_EXTRAINFO_TAG 0
/* ELQ = "Execute Load Query" */
#define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
@@ -510,6 +521,17 @@ struct sql_ex_info
#define LOG_EVENT_RELAY_LOG_F 0x40
/**
+ @def LOG_EVENT_IGNORABLE_F
+
+ For an event, 'e', carrying a type code, that a slave,
+ 's', does not recognize, 's' will check 'e' for
+ LOG_EVENT_IGNORABLE_F, and if the flag is set, then 'e'
+ is ignored. Otherwise, 's' acknowledges that it has
+ found an unknown event in the relay log.
+*/
+#define LOG_EVENT_IGNORABLE_F 0x80
+
+/**
@def LOG_EVENT_SKIP_REPLICATION_F
Flag set by application creating the event (with @@skip_replication); the
@@ -549,7 +571,7 @@ struct sql_ex_info
/* Shouldn't be defined before */
#define EXPECTED_OPTIONS \
- ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) << 19))
+ ((1ULL << 14) | (1ULL << 26) | (1ULL << 27) | (1ULL << 19))
#if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS
#error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values!
@@ -572,6 +594,40 @@ enum enum_binlog_checksum_alg {
#define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN
#define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */
+/*
+ These are capability numbers for MariaDB slave servers.
+
+ Newer MariaDB slaves set this to inform the master about their capabilities.
+ This allows the master to decide which events it can send to the slave
+ without breaking replication on old slaves that maybe do not understand
+ all events from newer masters.
+
+ As new releases are backwards compatible, a given capability implies also
+ all capabilities with smaller number.
+
+ Older MariaDB slaves and other MySQL slave servers do not set this, so they
+ are recorded with capability 0.
+*/
+
+/* MySQL or old MariaDB slave with no announced capability. */
+#define MARIA_SLAVE_CAPABILITY_UNKNOWN 0
+/* MariaDB >= 5.3, which understands ANNOTATE_ROWS_EVENT. */
+#define MARIA_SLAVE_CAPABILITY_ANNOTATE 1
+/*
+ MariaDB >= 5.5. This version has the capability to tolerate events omitted
+ from the binlog stream without breaking replication (MySQL slaves fail
+ because they mis-compute the offsets into the master's binlog).
+*/
+#define MARIA_SLAVE_CAPABILITY_TOLERATE_HOLES 2
+/* MariaDB >= 10.0, which knows about binlog_checkpoint_log_event. */
+#define MARIA_SLAVE_CAPABILITY_BINLOG_CHECKPOINT 3
+/* MariaDB >= 10.0.1, which knows about global transaction id events. */
+#define MARIA_SLAVE_CAPABILITY_GTID 4
+
+/* Our capability. */
+#define MARIA_SLAVE_CAPABILITY_MINE MARIA_SLAVE_CAPABILITY_GTID
+
+
/**
@enum Log_event_type
@@ -619,11 +675,12 @@ enum Log_event_type
PRE_GA_DELETE_ROWS_EVENT = 22,
/*
- These event numbers are used from 5.1.16 and forward
+ These event numbers are used from 5.1.16 until mysql-5.6.6,
+ and in MariaDB
*/
- WRITE_ROWS_EVENT = 23,
- UPDATE_ROWS_EVENT = 24,
- DELETE_ROWS_EVENT = 25,
+ WRITE_ROWS_EVENT_V1 = 23,
+ UPDATE_ROWS_EVENT_V1 = 24,
+ DELETE_ROWS_EVENT_V1 = 25,
/*
Something out of the ordinary happened on the master
@@ -637,6 +694,27 @@ enum Log_event_type
HEARTBEAT_LOG_EVENT= 27,
/*
+ In some situations, it is necessary to send over ignorable
+ data to the slave: data that a slave can handle in case there
+ is code for handling it, but which can be ignored if it is not
+ recognized.
+
+ These mysql-5.6 events are not recognized (and ignored) by MariaDB
+ */
+ IGNORABLE_LOG_EVENT= 28,
+ ROWS_QUERY_LOG_EVENT= 29,
+
+ /* Version 2 of the Row events, generated only by mysql-5.6.6+ */
+ WRITE_ROWS_EVENT = 30,
+ UPDATE_ROWS_EVENT = 31,
+ DELETE_ROWS_EVENT = 32,
+
+ /* MySQL 5.6 GTID events, ignored by MariaDB */
+ GTID_LOG_EVENT= 33,
+ ANONYMOUS_GTID_LOG_EVENT= 34,
+ PREVIOUS_GTIDS_LOG_EVENT= 35,
+
+ /*
Add new events here - right above this comment!
Existing events (except ENUM_END_EVENT) should never change their numbers
*/
@@ -647,6 +725,26 @@ enum Log_event_type
MARIA_EVENTS_BEGIN= 160,
/* New Maria event numbers start from here */
ANNOTATE_ROWS_EVENT= 160,
+ /*
+ Binlog checkpoint event. Used for XA crash recovery on the master, not used
+ in replication.
+ A binlog checkpoint event specifies a binlog file such that XA crash
+ recovery can start from that file - and it is guaranteed to find all XIDs
+ that are prepared in storage engines but not yet committed.
+ */
+ BINLOG_CHECKPOINT_EVENT= 161,
+ /*
+ Gtid event. For global transaction ID, used to start a new event group,
+ instead of the old BEGIN query event, and also to mark stand-alone
+ events.
+ */
+ GTID_EVENT= 162,
+ /*
+ Gtid list event. Logged at the start of every binlog, to record the
+ current replication state. This consists of the last GTID seen for
+ each replication domain.
+ */
+ GTID_LIST_EVENT= 163,
/* Add new MariaDB events here - right above this comment! */
@@ -719,6 +817,11 @@ typedef struct st_print_event_info
uint charset_database_number;
uint thread_id;
bool thread_id_printed;
+ uint32 server_id;
+ bool server_id_printed;
+ uint32 domain_id;
+ bool domain_id_printed;
+
/*
Track when @@skip_replication changes so we need to output a SET
statement for it.
@@ -1187,6 +1290,7 @@ public:
#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
+ virtual my_off_t get_header_len(my_off_t len) { return len; }
void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }
void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
@@ -1251,9 +1355,9 @@ public:
@see do_apply_event
*/
- int apply_event(Relay_log_info const *rli)
+ int apply_event(rpl_group_info *rgi)
{
- return do_apply_event(rli);
+ return do_apply_event(rgi);
}
@@ -1265,9 +1369,9 @@ public:
@see do_update_pos
*/
- int update_pos(Relay_log_info *rli)
+ int update_pos(rpl_group_info *rgi)
{
- return do_update_pos(rli);
+ return do_update_pos(rgi);
}
/**
@@ -1276,11 +1380,66 @@ public:
@see do_shall_skip
*/
- enum_skip_reason shall_skip(Relay_log_info *rli)
+ enum_skip_reason shall_skip(rpl_group_info *rgi)
+ {
+ return do_shall_skip(rgi);
+ }
+
+
+ /*
+ Check if an event is non-final part of a stand-alone event group,
+ such as Intvar_log_event (such events should be processed as part
+ of the following event group, not individually).
+ See also is_part_of_group()
+ */
+ static bool is_part_of_group(enum Log_event_type ev_type)
{
- return do_shall_skip(rli);
+ switch (ev_type)
+ {
+ case GTID_EVENT:
+ case INTVAR_EVENT:
+ case RAND_EVENT:
+ case USER_VAR_EVENT:
+ case TABLE_MAP_EVENT:
+ case ANNOTATE_ROWS_EVENT:
+ return true;
+ case DELETE_ROWS_EVENT:
+ case UPDATE_ROWS_EVENT:
+ case WRITE_ROWS_EVENT:
+ /*
+ ToDo: also check for non-final Rows_log_event (though such events
+ are usually in a BEGIN-COMMIT group).
+ */
+ default:
+ return false;
+ }
}
+ /*
+ Same as above, but works on the object. In addition this is true for all
+ rows event except the last one.
+ */
+ virtual bool is_part_of_group() { return 0; }
+ static bool is_group_event(enum Log_event_type ev_type)
+ {
+ switch (ev_type)
+ {
+ case START_EVENT_V3:
+ case STOP_EVENT:
+ case ROTATE_EVENT:
+ case SLAVE_EVENT:
+ case FORMAT_DESCRIPTION_EVENT:
+ case INCIDENT_EVENT:
+ case HEARTBEAT_LOG_EVENT:
+ case BINLOG_CHECKPOINT_EVENT:
+ case GTID_LIST_EVENT:
+ return false;
+
+ default:
+ return true;
+ }
+ }
+
protected:
/**
@@ -1293,14 +1452,14 @@ protected:
A typical usage is:
@code
- enum_skip_reason do_shall_skip(Relay_log_info *rli) {
- return continue_group(rli);
+ enum_skip_reason do_shall_skip(rpl_group_info *rgi) {
+ return continue_group(rgi);
}
@endcode
@return Skip reason
*/
- enum_skip_reason continue_group(Relay_log_info *rli);
+ enum_skip_reason continue_group(rpl_group_info *rgi);
/**
Primitive to apply an event to the database.
@@ -1317,7 +1476,7 @@ protected:
@retval 0 Event applied successfully
@retval errno Error code if event application failed
*/
- virtual int do_apply_event(Relay_log_info const *rli)
+ virtual int do_apply_event(rpl_group_info *rgi)
{
return 0; /* Default implementation does nothing */
}
@@ -1346,7 +1505,7 @@ protected:
1). Observe that handler errors are returned by the
do_apply_event() function, and not by this one.
*/
- virtual int do_update_pos(Relay_log_info *rli);
+ virtual int do_update_pos(rpl_group_info *rgi);
/**
@@ -1378,7 +1537,7 @@ protected:
The event shall be skipped because the slave skip counter was
non-zero. The caller shall decrease the counter by one.
*/
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -1853,6 +2012,8 @@ public:
my_free(data_buf);
}
Log_event_type get_type_code() { return QUERY_EVENT; }
+ static int dummy_event(String *packet, ulong ev_offset, uint8 checksum_alg);
+ static int begin_event(String *packet, ulong ev_offset, uint8 checksum_alg);
#ifdef MYSQL_SERVER
bool write(IO_CACHE* file);
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
@@ -1860,7 +2021,7 @@ public:
bool is_valid() const { return query != 0; }
/*
- Returns number of bytes additionaly written to post header by derived
+ Returns number of bytes additionally written to post header by derived
events (so far it is only Execute_load_query event).
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
@@ -1868,13 +2029,15 @@ public:
public: /* !!! Public in this patch to allow old usage */
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
- int do_apply_event(Relay_log_info const *rli,
+ int do_apply_event(rpl_group_info *rgi,
const char *query_arg,
uint32 q_len_arg);
+ static bool peek_is_commit_rollback(const char *event_start,
+ size_t event_len, uint8 checksum_alg);
#endif /* HAVE_REPLICATION */
/*
If true, the event always be applied by slave SQL thread or be printed by
@@ -1898,6 +2061,9 @@ public: /* !!! Public in this patch to allow old usage */
!strncasecmp(query, "SAVEPOINT", 9) ||
!strncasecmp(query, "ROLLBACK", 8);
}
+ bool is_begin() { return !strcmp(query, "BEGIN"); }
+ bool is_commit() { return !strcmp(query, "COMMIT"); }
+ bool is_rollback() { return !strcmp(query, "ROLLBACK"); }
};
@@ -1984,7 +2150,7 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const* rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
@@ -2297,12 +2463,12 @@ public:
public: /* !!! Public in this patch to allow old usage */
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const* rli)
+ virtual int do_apply_event(rpl_group_info *rgi)
{
- return do_apply_event(thd->slave_net,rli,0);
+ return do_apply_event(thd->slave_net,rgi,0);
}
- int do_apply_event(NET *net, Relay_log_info const *rli,
+ int do_apply_event(NET *net, rpl_group_info *rgi,
bool use_rli_only_for_errors);
#endif
};
@@ -2370,6 +2536,8 @@ public:
const Format_description_log_event* description_event);
~Start_log_event_v3() {}
Log_event_type get_type_code() { return START_EVENT_V3;}
+ my_off_t get_header_len(my_off_t l __attribute__((unused)))
+ { return LOG_EVENT_MINIMAL_HEADER_LEN; }
#ifdef MYSQL_SERVER
bool write(IO_CACHE* file);
#endif
@@ -2381,14 +2549,14 @@ public:
protected:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info*)
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info*)
{
/*
Events from ourself should be skipped, but they should not
decrease the slave skip counter.
*/
- if (this->server_id == ::server_id)
+ if (this->server_id == global_system_variables.server_id)
return Log_event::EVENT_SKIP_IGNORE;
else
return Log_event::EVENT_SKIP_NOT;
@@ -2477,9 +2645,9 @@ public:
static bool is_version_before_checksum(const master_version_split *version_split);
protected:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -2553,12 +2721,13 @@ Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg,
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+ bool is_part_of_group() { return 1; }
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -2632,12 +2801,13 @@ class Rand_log_event: public Log_event
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+ bool is_part_of_group() { return 1; }
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -2684,8 +2854,8 @@ class Xid_log_event: public Log_event
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -2753,12 +2923,13 @@ public:
void set_deferred(query_id_t qid) { deferred= true; query_id= qid; }
#endif
bool is_valid() const { return name != 0; }
+ bool is_part_of_group() { return 1; }
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -2791,14 +2962,14 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli)
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi)
{
/*
Events from ourself should be skipped, but they should not
decrease the slave skip counter.
*/
- if (this->server_id == ::server_id)
+ if (this->server_id == global_system_variables.server_id)
return Log_event::EVENT_SKIP_IGNORE;
else
return Log_event::EVENT_SKIP_NOT;
@@ -2885,6 +3056,8 @@ public:
my_free((void*) new_log_ident);
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
+ my_off_t get_header_len(my_off_t l __attribute__((unused)))
+ { return LOG_EVENT_MINIMAL_HEADER_LEN; }
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() const { return new_log_ident != 0; }
#ifdef MYSQL_SERVER
@@ -2893,9 +3066,262 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
+#endif
+};
+
+
+class Binlog_checkpoint_log_event: public Log_event
+{
+public:
+ char *binlog_file_name;
+ uint binlog_file_len;
+
+#ifdef MYSQL_SERVER
+ Binlog_checkpoint_log_event(const char *binlog_file_name_arg,
+ uint binlog_file_len_arg);
+#ifdef HAVE_REPLICATION
+ void pack_info(THD *thd, Protocol *protocol);
+#endif
+#else
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+ Binlog_checkpoint_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+ ~Binlog_checkpoint_log_event() { my_free(binlog_file_name); }
+ Log_event_type get_type_code() { return BINLOG_CHECKPOINT_EVENT;}
+ int get_data_size() { return binlog_file_len + BINLOG_CHECKPOINT_HEADER_LEN;}
+ bool is_valid() const { return binlog_file_name != 0; }
+#ifdef MYSQL_SERVER
+ bool write(IO_CACHE* file);
+ enum_skip_reason do_shall_skip(rpl_group_info *rgi);
+#endif
+};
+
+
+/**
+ @class Gtid_log_event
+
+ This event is logged as part of every event group to give the global
+ transaction id (GTID) of that group.
+
+ It replaces the BEGIN query event used in earlier versions to begin most
+ event groups, but is also used for events that used to be stand-alone.
+
+ @section Gtid_log_event_binary_format Binary Format
+
+ The binary format for Gtid_log_event has 6 extra reserved bytes to make the
+ length a total of 19 byte (+ 19 bytes of header in common with all events).
+ This is just the minimal size for a BEGIN query event, which makes it easy
+ to replace this event with such BEGIN event to remain compatible with old
+ slave servers.
+
+ <table>
+ <caption>Post-Header</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>seq_no</td>
+ <td>8 byte unsigned integer</td>
+ <td>increasing id within one server_id. Starts at 1, holes in the sequence
+ may occur</td>
+ </tr>
+
+ <tr>
+ <td>domain_id</td>
+ <td>4 byte unsigned integer</td>
+ <td>Replication domain id, identifying independent replication streams></td>
+ </tr>
+
+ <tr>
+ <td>flags</td>
+ <td>1 byte bitfield</td>
+ <td>Bit 0 set indicates stand-alone event (no terminating COMMIT)</td>
+ <td>Bit 1 set indicates group commit, and that commit id exists</td>
+ </tr>
+
+ <tr>
+ <td>Reserved (no group commit) / commit id (group commit) (see flags bit 1)</td>
+ <td>6 bytes / 8 bytes</td>
+ <td>Reserved bytes, set to 0. Maybe be used for future expansion (no
+ group commit). OR commit id, same for all GTIDs in the same group
+ commit (see flags bit 1).</td>
+ </tr>
+ </table>
+
+ The Body of Gtid_log_event is empty. The total event size is 19 bytes +
+ the normal 19 bytes common-header.
+*/
+
+class Gtid_log_event: public Log_event
+{
+public:
+ uint64 seq_no;
+ uint64 commit_id;
+ uint32 domain_id;
+ uchar flags2;
+
+ /* Flags2. */
+
+ /* FL_STANDALONE is set when there is no terminating COMMIT event. */
+ static const uchar FL_STANDALONE= 1;
+ /*
+ FL_GROUP_COMMIT_ID is set when event group is part of a group commit on the
+ master. Groups with same commit_id are part of the same group commit.
+ */
+ static const uchar FL_GROUP_COMMIT_ID= 2;
+
+#ifdef MYSQL_SERVER
+ Gtid_log_event(THD *thd_arg, uint64 seq_no, uint32 domain_id, bool standalone,
+ uint16 flags, bool is_transactional, uint64 commit_id);
+#ifdef HAVE_REPLICATION
+ void pack_info(THD *thd, Protocol *protocol);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
+#endif
+#else
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+ Gtid_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+ ~Gtid_log_event() { }
+ Log_event_type get_type_code() { return GTID_EVENT; }
+ int get_data_size()
+ {
+ return GTID_HEADER_LEN + ((flags2 & FL_GROUP_COMMIT_ID) ? 2 : 0);
+ }
+ bool is_valid() const { return seq_no != 0; }
+#ifdef MYSQL_SERVER
+ bool write(IO_CACHE *file);
+ static int make_compatible_event(String *packet, bool *need_dummy_event,
+ ulong ev_offset, uint8 checksum_alg);
+ static bool peek(const char *event_start, size_t event_len,
+ uint8 checksum_alg,
+ uint32 *domain_id, uint32 *server_id, uint64 *seq_no,
+ uchar *flags2, const Format_description_log_event *fdev);
+#endif
+};
+
+
+/**
+ @class Gtid_list_log_event
+
+ This event is logged at the start of every binlog file to record the
+ current replication state: the last global transaction id (GTID) applied
+ on the server within each replication domain.
+
+ It consists of a list of GTIDs, one for each replication domain ever seen
+ on the server.
+
+ @section Gtid_list_log_event_binary_format Binary Format
+
+ <table>
+ <caption>Post-Header</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>count</td>
+ <td>4 byte unsigned integer</td>
+ <td>The lower 28 bits are the number of GTIDs. The upper 4 bits are
+ flags bits.</td>
+ </tr>
+ </table>
+
+ <table>
+ <caption>Body</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>domain_id</td>
+ <td>4 byte unsigned integer</td>
+ <td>Replication domain id of one GTID</td>
+ </tr>
+
+ <tr>
+ <td>server_id</td>
+ <td>4 byte unsigned integer</td>
+ <td>Server id of one GTID</td>
+ </tr>
+
+ <tr>
+ <td>seq_no</td>
+ <td>8 byte unsigned integer</td>
+ <td>sequence number of one GTID</td>
+ </tr>
+ </table>
+
+ The three elements in the body repeat COUNT times to form the GTID list.
+
+ At the time of writing, only one flag bit is in use.
+
+ Bit 28 of `count' is used for flag FLAG_UNTIL_REACHED, which is sent in a
+ Gtid_list event from the master to the slave to indicate that the START
+ SLAVE UNTIL master_gtid_pos=xxx condition has been reached. (This flag is
+ only sent in "fake" events generated on the fly, it is not written into
+ the binlog).
+*/
+
+class Gtid_list_log_event: public Log_event
+{
+public:
+ uint32 count;
+ uint32 gl_flags;
+ struct rpl_gtid *list;
+ uint64 *sub_id_list;
+
+ static const uint element_size= 4+4+8;
+ static const uint32 FLAG_UNTIL_REACHED= (1<<28);
+ static const uint32 FLAG_IGN_GTIDS= (1<<29);
+
+#ifdef MYSQL_SERVER
+ Gtid_list_log_event(rpl_binlog_state *gtid_set, uint32 gl_flags);
+ Gtid_list_log_event(slave_connection_state *gtid_set, uint32 gl_flags);
+#ifdef HAVE_REPLICATION
+ void pack_info(THD *thd, Protocol *protocol);
+#endif
+#else
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+ Gtid_list_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+ ~Gtid_list_log_event() { my_free(list); my_free(sub_id_list); }
+ Log_event_type get_type_code() { return GTID_LIST_EVENT; }
+ int get_data_size() {
+ /*
+ Replacing with dummy event, needed for older slaves, requires a minimum
+ of 6 bytes in the body.
+ */
+ return (count==0 ?
+ GTID_LIST_HEADER_LEN+2 : GTID_LIST_HEADER_LEN+count*element_size);
+ }
+ bool is_valid() const { return list != NULL; }
+#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+ bool to_packet(String *packet);
+ bool write(IO_CACHE *file);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
+ static bool peek(const char *event_start, uint32 event_len,
+ uint8 checksum_alg,
+ rpl_gtid **out_gtid_list, uint32 *out_list_len,
+ const Format_description_log_event *fdev);
};
@@ -2970,7 +3396,7 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
@@ -3025,7 +3451,7 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
@@ -3066,7 +3492,7 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
@@ -3106,7 +3532,7 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
@@ -3139,7 +3565,7 @@ public:
Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; }
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
};
@@ -3205,7 +3631,7 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
};
@@ -3261,6 +3687,7 @@ public:
virtual int get_data_size();
virtual Log_event_type get_type_code();
virtual bool is_valid() const;
+ virtual bool is_part_of_group() { return 1; }
#ifndef MYSQL_CLIENT
virtual bool write_data_header(IO_CACHE*);
@@ -3277,9 +3704,9 @@ public:
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
private:
- virtual int do_apply_event(Relay_log_info const*);
- virtual int do_update_pos(Relay_log_info*);
- virtual enum_skip_reason do_shall_skip(Relay_log_info*);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info*);
#endif
private:
@@ -3642,7 +4069,9 @@ public:
enum
{
TM_NO_FLAGS = 0U,
- TM_BIT_LEN_EXACT_F = (1U << 0)
+ TM_BIT_LEN_EXACT_F = (1U << 0),
+ // MariaDB flags (we starts from the other end)
+ TM_BIT_HAS_TRIGGERS_F= (1U << 14)
};
flag_set get_flags(flag_set flag) const { return m_flags & flag; }
@@ -3672,6 +4101,7 @@ public:
virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }
+ virtual bool is_part_of_group() { return 1; }
virtual int get_data_size() { return (uint) m_data_size; }
#ifdef MYSQL_SERVER
@@ -3692,9 +4122,9 @@ public:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
#endif
#ifdef MYSQL_SERVER
@@ -3793,6 +4223,9 @@ public:
void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; }
flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+ Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */
+ virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */
+
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual void pack_info(THD *thd, Protocol *protocol);
#endif
@@ -3837,9 +4270,16 @@ public:
{
return m_rows_buf && m_cols.bitmap;
}
+ bool is_part_of_group() { return get_flags(STMT_END_F) != 0; }
uint m_row_count; /* The number of rows added to the event */
+ const uchar* get_extra_row_data() const { return m_extra_row_data; }
+
+#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+ virtual uint8 get_trg_event_map()= 0;
+#endif
+
protected:
/*
The constructors are protected since you're supposed to inherit
@@ -3847,10 +4287,10 @@ protected:
*/
#ifdef MYSQL_SERVER
Rows_log_event(THD*, TABLE*, ulong table_id,
- MY_BITMAP const *cols, bool is_transactional);
+ MY_BITMAP const *cols, bool is_transactional,
+ Log_event_type event_type);
#endif
Rows_log_event(const char *row_data, uint event_len,
- Log_event_type event_type,
const Format_description_log_event *description_event);
#ifdef MYSQL_CLIENT
@@ -3888,6 +4328,12 @@ protected:
flag_set m_flags; /* Flags for row-level events */
+ Log_event_type m_type; /* Actual event type */
+
+ uchar *m_extra_row_data; /* Pointer to extra row data if any */
+ /* If non null, first byte is length */
+
+
/* helper functions */
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
@@ -3896,20 +4342,24 @@ protected:
uchar *m_key; /* Buffer to keep key value during searches */
KEY *m_key_info; /* Pointer to KEY info for m_key_nr */
uint m_key_nr; /* Key number */
+ bool master_had_triggers; /* set after tables opening */
int find_key(); // Find a best key to use in find_row()
- int find_row(const Relay_log_info *const);
- int write_row(const Relay_log_info *const, const bool);
+ int find_row(rpl_group_info *);
+ int write_row(rpl_group_info *, const bool);
// Unpack the current row into m_table->record[0]
- int unpack_current_row(const Relay_log_info *const rli)
+ int unpack_current_row(rpl_group_info *rgi)
{
DBUG_ASSERT(m_table);
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
- return ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
+ return ::unpack_row(rgi, m_table, m_width, m_curr_row, &m_cols,
&m_curr_row_end, &m_master_reclength, m_rows_end);
}
+ bool process_triggers(trg_event_type event,
+ trg_action_time_type time_type,
+ bool old_row_is_record1);
/**
Helper function to check whether there is an auto increment
@@ -3929,9 +4379,9 @@ protected:
private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
- virtual int do_update_pos(Relay_log_info *rli);
- virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
+ virtual int do_update_pos(rpl_group_info *rgi);
+ virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi);
/*
Primitive to prepare for a sequence of row executions.
@@ -3982,7 +4432,7 @@ private:
0 if execution succeeded, 1 if execution failed.
*/
- virtual int do_exec_row(const Relay_log_info *const rli) = 0;
+ virtual int do_exec_row(rpl_group_info *rli) = 0;
#endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */
friend class Old_rows_log_event;
@@ -4028,8 +4478,12 @@ public:
}
#endif
+#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+ uint8 get_trg_event_map();
+#endif
+
private:
- virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+ virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
#ifdef MYSQL_CLIENT
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
@@ -4038,7 +4492,7 @@ private:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_before_row_operations(const Slave_reporting_capability *const);
virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
- virtual int do_exec_row(const Relay_log_info *const);
+ virtual int do_exec_row(rpl_group_info *);
#endif
};
@@ -4102,8 +4556,12 @@ public:
return Rows_log_event::is_valid() && m_cols_ai.bitmap;
}
+#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+ uint8 get_trg_event_map();
+#endif
+
protected:
- virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+ virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
#ifdef MYSQL_CLIENT
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
@@ -4112,7 +4570,7 @@ protected:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_before_row_operations(const Slave_reporting_capability *const);
virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
- virtual int do_exec_row(const Relay_log_info *const);
+ virtual int do_exec_row(rpl_group_info *);
#endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */
};
@@ -4166,9 +4624,13 @@ public:
cols, fields, before_record);
}
#endif
-
+
+#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+ uint8 get_trg_event_map();
+#endif
+
protected:
- virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+ virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
#ifdef MYSQL_CLIENT
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
@@ -4177,7 +4639,7 @@ protected:
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
virtual int do_before_row_operations(const Slave_reporting_capability *const);
virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
- virtual int do_exec_row(const Relay_log_info *const);
+ virtual int do_exec_row(rpl_group_info *);
#endif
};
@@ -4241,7 +4703,16 @@ public:
{
DBUG_ENTER("Incident_log_event::Incident_log_event");
DBUG_PRINT("enter", ("m_incident: %d", m_incident));
- m_message= msg;
+ m_message.str= NULL;
+ m_message.length= 0;
+ if (!(m_message.str= (char*) my_malloc(msg.length+1, MYF(MY_WME))))
+ {
+ /* Mark this event invalid */
+ m_incident= INCIDENT_NONE;
+ DBUG_VOID_RETURN;
+ }
+ strmake(m_message.str, msg.str, msg.length);
+ m_message.length= msg.length;
set_direct_logging();
/* Replicate the incident irregardless of @@skip_replication. */
flags&= ~LOG_EVENT_SKIP_REPLICATION_F;
@@ -4263,7 +4734,7 @@ public:
#endif
#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
- virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_apply_event(rpl_group_info *rgi);
#endif
virtual bool write_data_header(IO_CACHE *file);
@@ -4286,6 +4757,60 @@ private:
LEX_STRING m_message;
};
+/**
+ @class Ignorable_log_event
+
+ Base class for ignorable log events. Events deriving from
+ this class can be safely ignored by slaves that cannot
+ recognize them. Newer slaves, will be able to read and
+ handle them. This has been designed to be an open-ended
+ architecture, so adding new derived events shall not harm
+ the old slaves that support ignorable log event mechanism
+ (they will just ignore unrecognized ignorable events).
+
+ @note The only thing that makes an event ignorable is that it has
+ the LOG_EVENT_IGNORABLE_F flag set. It is not strictly necessary
+ that ignorable event types derive from Ignorable_log_event; they may
+ just as well derive from Log_event and pass LOG_EVENT_IGNORABLE_F as
+ argument to the Log_event constructor.
+**/
+
+class Ignorable_log_event : public Log_event {
+public:
+ int number;
+ const char *description;
+
+#ifndef MYSQL_CLIENT
+ Ignorable_log_event(THD *thd_arg)
+ :Log_event(thd_arg, LOG_EVENT_IGNORABLE_F, FALSE),
+ number(0), description("internal")
+ {
+ DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
+ DBUG_VOID_RETURN;
+ }
+#endif
+
+ Ignorable_log_event(const char *buf,
+ const Format_description_log_event *descr_event,
+ const char *event_name);
+ virtual ~Ignorable_log_event();
+
+#ifndef MYSQL_CLIENT
+ void pack_info(THD *, Protocol*);
+#endif
+
+#ifdef MYSQL_CLIENT
+ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+ virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; }
+
+ virtual bool is_valid() const { return 1; }
+
+ virtual int get_data_size() { return IGNORABLE_HEADER_LEN; }
+};
+
+
static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
FILE *file)
{
@@ -4338,27 +4863,15 @@ private:
bool slave_execute_deferred_events(THD *thd);
#endif
-int append_query_string(THD *thd, CHARSET_INFO *csinfo,
- String const *from, String *to);
-
bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos,
const char **group_relay_log_name,
ulonglong *relay_log_pos);
bool event_checksum_test(uchar *buf, ulong event_len, uint8 alg);
+bool event_that_should_be_ignored(const char *buf);
uint8 get_checksum_alg(const char* buf, ulong len);
extern TYPELIB binlog_checksum_typelib;
-#ifndef MYSQL_CLIENT
-/**
- The function is called by slave applier in case there are
- active table filtering rules to force gathering events associated
- with Query-log-event into an array to execute
- them once the fate of the Query is determined for execution.
-*/
-bool slave_execute_deferred_events(THD *thd);
-#endif
-
/**
@} (end of group Replication)
*/