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.h1214
1 files changed, 1114 insertions, 100 deletions
diff --git a/sql/log_event.h b/sql/log_event.h
index 04aac5d08fc..0c66d1b190f 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -13,18 +13,30 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/**
+ @addtogroup Replication
+ @{
+
+ @file
+
+ Binary log event definitions.
+*/
+
#ifndef _log_event_h
#define _log_event_h
-#ifdef __EMX__
-#undef write // remove pthread.h macro definition, conflict with write() class member
-#endif
-
#if defined(USE_PRAGMA_INTERFACE) && !defined(MYSQL_CLIENT)
#pragma interface /* gcc class implementation */
#endif
+#include <my_bitmap.h>
+#include "rpl_constants.h"
+#ifndef MYSQL_CLIENT
+#include "rpl_record.h"
+#include "rpl_reporting.h"
+#endif
+
#define LOG_READ_EOF -1
#define LOG_READ_BOGUS -2
#define LOG_READ_IO -3
@@ -58,8 +70,8 @@
which increments every time we write an event to the binlog) (3 bytes).
Q: how do we handle when the counter is overflowed and restarts from 0 ?
- - Query and Load (Create or Execute) events may have a more precise timestamp
- (with microseconds), number of matched/affected/warnings rows
+ - Query and Load (Create or Execute) events may have a more precise
+ timestamp (with microseconds), number of matched/affected/warnings rows
and fields of session variables: SQL_MODE,
FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and
charsets, the PASSWORD() version (old/new/...).
@@ -196,9 +208,11 @@ struct sql_ex_info
#define EXEC_LOAD_HEADER_LEN 4
#define DELETE_FILE_HEADER_LEN 4
#define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
+#define ROWS_HEADER_LEN 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
/*
Max number of possible extra bytes in a replication event compared to a
packet (i.e. a query) sent from client to master;
@@ -323,6 +337,14 @@ struct sql_ex_info
/* DF = "Delete File" */
#define DF_FILE_ID_OFFSET 0
+/* TM = "Table Map" */
+#define TM_MAPID_OFFSET 0
+#define TM_FLAGS_OFFSET 6
+
+/* RW = "RoWs" */
+#define RW_MAPID_OFFSET 0
+#define RW_FLAGS_OFFSET 6
+
/* ELQ = "Execute Load Query" */
#define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
#define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4
@@ -394,6 +416,12 @@ struct sql_ex_info
#define LOG_EVENT_SUPPRESS_USE_F 0x8
/*
+ The table map version internal to the log should be increased after
+ the event has been written to the binary log.
+ */
+#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x10
+
+/*
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must be
written to the binlog. OPTIONS_WRITTEN_TO_BINLOG could be written
into the Format_description_log_event, so that if later we don't want
@@ -411,12 +439,18 @@ struct sql_ex_info
either, as the manual says (because a too big in-memory temp table is
automatically written to disk).
*/
-#define OPTIONS_WRITTEN_TO_BIN_LOG (OPTION_AUTO_IS_NULL | \
-OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS)
+#define OPTIONS_WRITTEN_TO_BIN_LOG \
+ (OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS | \
+ OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT)
-#if OPTIONS_WRITTEN_TO_BIN_LOG != ((1L << 14) | (1L << 26) | (1L << 27))
+/* Shouldn't be defined before */
+#define EXPECTED_OPTIONS \
+ ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) << 19))
+
+#if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS
#error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values!
#endif
+#undef EXPECTED_OPTIONS /* You shouldn't use this one */
enum Log_event_type
{
@@ -449,6 +483,28 @@ enum Log_event_type
BEGIN_LOAD_QUERY_EVENT= 17,
EXECUTE_LOAD_QUERY_EVENT= 18,
+ TABLE_MAP_EVENT = 19,
+
+ /*
+ These event numbers were used for 5.1.0 to 5.1.15 and are
+ therefore obsolete.
+ */
+ PRE_GA_WRITE_ROWS_EVENT = 20,
+ PRE_GA_UPDATE_ROWS_EVENT = 21,
+ PRE_GA_DELETE_ROWS_EVENT = 22,
+
+ /*
+ These event numbers are used from 5.1.16 and forward
+ */
+ WRITE_ROWS_EVENT = 23,
+ UPDATE_ROWS_EVENT = 24,
+ DELETE_ROWS_EVENT = 25,
+
+ /*
+ Something out of the ordinary happened on the master
+ */
+ INCIDENT_EVENT= 26,
+
/*
Add new events here - right above this comment!
Existing events (except ENUM_END_EVENT) should never change their numbers
@@ -472,13 +528,12 @@ enum Int_event_type
#ifndef MYSQL_CLIENT
class String;
-class MYSQL_LOG;
+class MYSQL_BIN_LOG;
class THD;
#endif
class Format_description_log_event;
-
-struct st_relay_log_info;
+class Relay_log_info;
#ifdef MYSQL_CLIENT
/*
@@ -524,15 +579,35 @@ typedef struct st_print_event_info
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
- strcpy(delimiter, ";");
+ delimiter[0]= ';';
+ delimiter[1]= 0;
+ myf const flags = MYF(MY_WME | MY_NABP);
+ open_cached_file(&head_cache, NULL, NULL, 0, flags);
+ open_cached_file(&body_cache, NULL, NULL, 0, flags);
}
+ ~st_print_event_info() {
+ close_cached_file(&head_cache);
+ close_cached_file(&body_cache);
+ }
+ bool init_ok() /* tells if construction was successful */
+ { return my_b_inited(&head_cache) && my_b_inited(&body_cache); }
+
+
/* Settings on how to print the events */
bool short_form;
+ bool base64_output;
my_off_t hexdump_from;
uint8 common_header_len;
char delimiter[16];
+ /*
+ These two caches are used by the row-based replication events to
+ collect the header information and the main body of the events
+ making up a statement.
+ */
+ IO_CACHE head_cache;
+ IO_CACHE body_cache;
} PRINT_EVENT_INFO;
#endif
@@ -547,6 +622,33 @@ typedef struct st_print_event_info
class Log_event
{
public:
+ /**
+ Enumeration of what kinds of skipping (and non-skipping) that can
+ occur when the slave executes an event.
+
+ @see shall_skip
+ @see do_shall_skip
+ */
+ enum enum_skip_reason {
+ /**
+ Don't skip event.
+ */
+ EVENT_SKIP_NOT,
+
+ /**
+ Skip event by ignoring it.
+
+ This means that the slave skip counter will not be changed.
+ */
+ EVENT_SKIP_IGNORE,
+
+ /**
+ Skip event and decrease skip counter.
+ */
+ EVENT_SKIP_COUNT
+ };
+
+
/*
The following type definition is to be used whenever data is placed
and manipulated in a common buffer. Use this typedef for buffers
@@ -617,7 +719,8 @@ public:
*/
static Log_event* read_log_event(IO_CACHE* file,
pthread_mutex_t* log_lock,
- const Format_description_log_event *description_event);
+ const Format_description_log_event
+ *description_event);
static int read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock);
/*
@@ -628,16 +731,14 @@ public:
static void init_show_field_list(List<Item>* field_list);
#ifdef HAVE_REPLICATION
int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
+
/*
pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends
a string to display to the user, so it resembles print().
*/
+
virtual void pack_info(Protocol *protocol);
- /*
- The SQL slave thread calls exec_event() to execute the event; this is where
- the slave's data is modified.
- */
- virtual int exec_event(struct st_relay_log_info* rli);
+
#endif /* HAVE_REPLICATION */
virtual const char* get_db()
{
@@ -647,22 +748,31 @@ public:
Log_event() : temp_buf(0) {}
/* avoid having to link mysqlbinlog against libpthread */
static Log_event* read_log_event(IO_CACHE* file,
- const Format_description_log_event *description_event);
+ const Format_description_log_event
+ *description_event);
/* print*() functions are used by mysqlbinlog */
- virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0) = 0;
- void print_timestamp(FILE* file, time_t *ts = 0);
- void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
+ void print_timestamp(IO_CACHE* file, time_t *ts = 0);
+ void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
+ bool is_more);
+ void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
+ bool is_more);
#endif
static void *operator new(size_t size)
{
return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
}
+
static void operator delete(void *ptr, size_t size)
{
- my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
+ my_free((uchar*) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
+ /* Placement version of the above operators */
+ static void *operator new(size_t, void* ptr) { return ptr; }
+ static void operator delete(void*, void*) { }
+
#ifndef MYSQL_CLIENT
bool write_header(IO_CACHE* file, ulong data_length);
virtual bool write(IO_CACHE* file)
@@ -675,12 +785,24 @@ public:
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
+ inline time_t get_time()
+ {
+ THD *tmp_thd;
+ if (when)
+ return when;
+ if (thd)
+ return thd->start_time;
+ if ((tmp_thd= current_thd))
+ return tmp_thd->start_time;
+ return my_time(0);
+ }
#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
virtual bool is_artificial_event() { return 0; }
- inline bool get_cache_stmt() { return cache_stmt; }
- Log_event(const char* buf, const Format_description_log_event* description_event);
+ inline bool get_cache_stmt() const { return cache_stmt; }
+ Log_event(const char* buf, const Format_description_log_event
+ *description_event);
virtual ~Log_event() { free_temp_buf();}
void register_temp_buf(char* buf) { temp_buf = buf; }
void free_temp_buf()
@@ -702,6 +824,130 @@ public:
*description_event);
/* returns the human readable name of the event's type */
const char* get_type_str();
+
+ /* Return start of query time or current time */
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+public:
+
+ /**
+ Apply the event to the database.
+
+ This function represents the public interface for applying an
+ event.
+
+ @see do_apply_event
+ */
+ int apply_event(Relay_log_info const *rli)
+ {
+ return do_apply_event(rli);
+ }
+
+
+ /**
+ Update the relay log position.
+
+ This function represents the public interface for "stepping over"
+ the event and will update the relay log information.
+
+ @see do_update_pos
+ */
+ int update_pos(Relay_log_info *rli)
+ {
+ return do_update_pos(rli);
+ }
+
+ /**
+ Decide if the event shall be skipped, and the reason for skipping
+ it.
+
+ @see do_shall_skip
+ */
+ enum_skip_reason shall_skip(Relay_log_info *rli)
+ {
+ return do_shall_skip(rli);
+ }
+
+protected:
+
+ /**
+ Primitive to apply an event to the database.
+
+ This is where the change to the database is made.
+
+ @note The primitive is protected instead of private, since there
+ is a hierarchy of actions to be performed in some cases.
+
+ @see Format_description_log_event::do_apply_event()
+
+ @param rli Pointer to relay log info structure
+
+ @retval 0 Event applied successfully
+ @retval errno Error code if event application failed
+ */
+ virtual int do_apply_event(Relay_log_info const *rli)
+ {
+ return 0; /* Default implementation does nothing */
+ }
+
+
+ /**
+ Advance relay log coordinates.
+
+ This function is called to advance the relay log coordinates to
+ just after the event. It is essential that both the relay log
+ coordinate and the group log position is updated correctly, since
+ this function is used also for skipping events.
+
+ Normally, each implementation of do_update_pos() shall:
+
+ - Update the event position to refer to the position just after
+ the event.
+
+ - Update the group log position to refer to the position just
+ after the event <em>if the event is last in a group</em>
+
+ @param rli Pointer to relay log info structure
+
+ @retval 0 Coordinates changed successfully
+ @retval errno Error code if advancing failed (usually just
+ 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);
+
+
+ /**
+ Decide if this event shall be skipped or not and the reason for
+ skipping it.
+
+ The default implementation decide that the event shall be skipped
+ if either:
+
+ - the server id of the event is the same as the server id of the
+ server and <code>rli->replicate_same_server_id</code> is true,
+ or
+
+ - if <code>rli->slave_skip_counter</code> is greater than zero.
+
+ @see do_apply_event
+ @see do_update_pos
+
+ @retval Log_event::EVENT_SKIP_NOT
+ The event shall not be skipped and should be applied.
+
+ @retval Log_event::EVENT_SKIP_IGNORE
+ The event shall be skipped by just ignoring it, i.e., the slave
+ skip counter shall not be changed. This happends if, for example,
+ the originating server id of the event is the same as the server
+ id of the slave.
+
+ @retval Log_event::EVENT_SKIP_COUNT
+ 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);
+#endif
};
/*
@@ -742,10 +988,10 @@ public:
uint16 error_code;
ulong thread_id;
/*
- For events created by Query_log_event::exec_event (and
- Load_log_event::exec_event()) we need the *original* thread id, to be able
- to log the event with the original (=master's) thread id (fix for
- BUG#1686).
+ For events created by Query_log_event::do_apply_event (and
+ Load_log_event::do_apply_event()) we need the *original* thread
+ id, to be able to log the event with the original (=master's)
+ thread id (fix for BUG#1686).
*/
ulong slave_proxy_id;
@@ -809,13 +1055,10 @@ public:
const char* get_db() { return db; }
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
- int exec_event(struct st_relay_log_info* rli, const char *query_arg,
- uint32 q_len_arg);
#endif /* HAVE_REPLICATION */
#else
- void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Query_log_event();
@@ -825,7 +1068,7 @@ public:
~Query_log_event()
{
if (data_buf)
- my_free((gptr) data_buf, MYF(0));
+ my_free((uchar*) data_buf, MYF(0));
}
Log_event_type get_type_code() { return QUERY_EVENT; }
#ifndef MYSQL_CLIENT
@@ -840,6 +1083,16 @@ public:
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
/* Writes derived event-specific part of post header. */
+
+public: /* !!! Public in this patch to allow old usage */
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+ virtual int do_update_pos(Relay_log_info *rli);
+
+ int do_apply_event(Relay_log_info const *rli,
+ const char *query_arg,
+ uint32 q_len_arg);
+#endif /* HAVE_REPLICATION */
};
@@ -888,11 +1141,10 @@ public:
uint16 master_port;
#ifndef MYSQL_CLIENT
- Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli);
+ Slave_log_event(THD* thd_arg, Relay_log_info* rli);
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Slave_log_event(const char* buf, uint event_len);
@@ -903,6 +1155,11 @@ public:
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const* rli);
+#endif
};
#endif /* HAVE_REPLICATION */
@@ -921,7 +1178,8 @@ private:
char **fn_start, char **fn_end);
protected:
int copy_log_event(const char *buf, ulong event_len,
- int body_offset, const Format_description_log_event* description_event);
+ int body_offset,
+ const Format_description_log_event* description_event);
public:
ulong thread_id;
@@ -972,15 +1230,9 @@ public:
const char* get_db() { return db; }
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli)
- {
- return exec_event(thd->slave_net,rli,0);
- }
- int exec_event(NET* net, struct st_relay_log_info* rli,
- bool use_rli_only_for_errors);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info = 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
#endif
@@ -1009,6 +1261,17 @@ public:
+ LOAD_HEADER_LEN
+ sql_ex.data_size() + field_block_len + num_fields);
}
+
+public: /* !!! Public in this patch to allow old usage */
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const* rli)
+ {
+ return do_apply_event(thd->slave_net,rli,0);
+ }
+
+ int do_apply_event(NET *net, Relay_log_info const *rli,
+ bool use_rli_only_for_errors);
+#endif
};
extern char server_version[SERVER_VERSION_LENGTH];
@@ -1061,16 +1324,20 @@ public:
setting log_event == 0 (for now).
*/
bool artificial_event;
+ /*
+ We set this to 1 if we don't want to have the created time in the log,
+ which is the case when we rollover to a new log.
+ */
+ bool dont_set_created;
#ifndef MYSQL_CLIENT
Start_log_event_v3();
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
Start_log_event_v3() {}
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Start_log_event_v3(const char* buf,
@@ -1086,6 +1353,22 @@ public:
return START_V3_HEADER_LEN; //no variable-sized part
}
virtual bool is_artificial_event() { return artificial_event; }
+
+protected:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+ virtual enum_skip_reason do_shall_skip(Relay_log_info*)
+ {
+ /*
+ Events from ourself should be skipped, but they should not
+ decrease the slave skip counter.
+ */
+ if (this->server_id == ::server_id)
+ return Log_event::EVENT_SKIP_IGNORE;
+ else
+ return Log_event::EVENT_SKIP_NOT;
+ }
+#endif
};
@@ -1111,16 +1394,10 @@ public:
uchar server_version_split[3];
Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
-
-#ifndef MYSQL_CLIENT
-#ifdef HAVE_REPLICATION
- int exec_event(struct st_relay_log_info* rli);
-#endif /* HAVE_REPLICATION */
-#endif
-
Format_description_log_event(const char* buf, uint event_len,
- const Format_description_log_event* description_event);
- ~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
+ const Format_description_log_event
+ *description_event);
+ ~Format_description_log_event() { my_free((uchar*)post_header_len, MYF(0)); }
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
@@ -1140,7 +1417,15 @@ public:
*/
return FORMAT_DESCRIPTION_HEADER_LEN;
}
+
void calc_server_version_split();
+
+protected:
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
};
@@ -1164,13 +1449,13 @@ public:
{}
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
- Intvar_log_event(const char* buf, const Format_description_log_event* description_event);
+ Intvar_log_event(const char* buf,
+ const Format_description_log_event *description_event);
~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;}
const char* get_var_type_name();
@@ -1179,6 +1464,13 @@ public:
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+
+private:
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
};
@@ -1205,13 +1497,13 @@ class Rand_log_event: public Log_event
{}
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
- Rand_log_event(const char* buf, const Format_description_log_event* description_event);
+ Rand_log_event(const char* buf,
+ const Format_description_log_event *description_event);
~Rand_log_event() {}
Log_event_type get_type_code() { return RAND_EVENT;}
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
@@ -1219,6 +1511,13 @@ class Rand_log_event: public Log_event
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+
+private:
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
};
/*****************************************************************************
@@ -1242,13 +1541,13 @@ class Xid_log_event: public Log_event
Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {}
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
- Xid_log_event(const char* buf, const Format_description_log_event* description_event);
+ Xid_log_event(const char* buf,
+ const Format_description_log_event *description_event);
~Xid_log_event() {}
Log_event_type get_type_code() { return XID_EVENT;}
int get_data_size() { return sizeof(xid); }
@@ -1256,6 +1555,11 @@ class Xid_log_event: public Log_event
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
};
/*****************************************************************************
@@ -1285,18 +1589,25 @@ public:
val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
{ is_null= !val; }
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
- User_var_log_event(const char* buf, const Format_description_log_event* description_event);
+ User_var_log_event(const char* buf,
+ const Format_description_log_event *description_event);
~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+
+private:
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
};
@@ -1311,17 +1622,33 @@ public:
#ifndef MYSQL_CLIENT
Stop_log_event() :Log_event()
{}
- int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
- Stop_log_event(const char* buf, const Format_description_log_event* description_event):
+ Stop_log_event(const char* buf,
+ const Format_description_log_event *description_event):
Log_event(buf, description_event)
{}
~Stop_log_event() {}
Log_event_type get_type_code() { return STOP_EVENT;}
bool is_valid() const { return 1; }
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_update_pos(Relay_log_info *rli);
+ virtual enum_skip_reason do_shall_skip(Relay_log_info *rli)
+ {
+ /*
+ Events from ourself should be skipped, but they should not
+ decrease the slave skip counter.
+ */
+ if (this->server_id == ::server_id)
+ return Log_event::EVENT_SKIP_IGNORE;
+ else
+ return Log_event::EVENT_SKIP_NOT;
+ }
+#endif
};
/*****************************************************************************
@@ -1343,15 +1670,14 @@ public:
uint ident_len;
uint flags;
#ifndef MYSQL_CLIENT
- Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
+ Rotate_log_event(const char* new_log_ident_arg,
uint ident_len_arg,
ulonglong pos_arg, uint flags);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Rotate_log_event(const char* buf, uint event_len,
@@ -1359,7 +1685,7 @@ public:
~Rotate_log_event()
{
if (flags & DUP_NAME)
- my_free((gptr) new_log_ident, MYF(MY_ALLOW_ZERO_PTR));
+ my_free((uchar*) new_log_ident, MYF(MY_ALLOW_ZERO_PTR));
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
@@ -1367,6 +1693,12 @@ public:
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_update_pos(Relay_log_info *rli);
+ virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
+#endif
};
@@ -1401,11 +1733,11 @@ public:
bool using_trans);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ bool enable_local);
#endif
Create_file_log_event(const char* buf, uint event_len,
@@ -1435,6 +1767,11 @@ public:
*/
bool write_base(IO_CACHE* file);
#endif
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
};
@@ -1467,24 +1804,29 @@ public:
Append_block_log_event(THD* thd, const char* db_arg, char* block_arg,
uint block_len_arg, bool using_trans);
#ifdef HAVE_REPLICATION
- int exec_event(struct st_relay_log_info* rli);
void pack_info(Protocol* protocol);
virtual int get_create_or_append() const;
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Append_block_log_event(const char* buf, uint event_len,
- const Format_description_log_event* description_event);
+ const Format_description_log_event
+ *description_event);
~Append_block_log_event() {}
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() const { return block != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
-#endif
const char* get_db() { return db; }
+#endif
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
};
@@ -1504,11 +1846,11 @@ public:
Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
+ bool enable_local);
#endif
Delete_file_log_event(const char* buf, uint event_len,
@@ -1519,8 +1861,13 @@ public:
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
-#endif
const char* get_db() { return db; }
+#endif
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
};
@@ -1540,22 +1887,27 @@ public:
Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Execute_load_log_event(const char* buf, uint event_len,
- const Format_description_log_event* description_event);
+ const Format_description_log_event
+ *description_event);
~Execute_load_log_event() {}
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
-#endif
const char* get_db() { return db; }
+#endif
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
};
@@ -1581,7 +1933,8 @@ public:
#endif /* HAVE_REPLICATION */
#endif
Begin_load_query_log_event(const char* buf, uint event_len,
- const Format_description_log_event* description_event);
+ const Format_description_log_event
+ *description_event);
~Begin_load_query_log_event() {}
Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; }
};
@@ -1625,16 +1978,16 @@ public:
bool using_trans, bool suppress_use);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
- int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
/* Prints the query as LOAD DATA LOCAL and with rewritten filename */
void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
const char *local_fname);
#endif
Execute_load_query_log_event(const char* buf, uint event_len,
- const Format_description_log_event *description_event);
+ const Format_description_log_event
+ *description_event);
~Execute_load_query_log_event() {}
Log_event_type get_type_code() { return EXECUTE_LOAD_QUERY_EVENT; }
@@ -1644,7 +1997,12 @@ public:
#ifndef MYSQL_CLIENT
bool write_post_header_for_derived(IO_CACHE* file);
#endif
- };
+
+private:
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
+};
#ifdef MYSQL_CLIENT
@@ -1656,14 +2014,670 @@ public:
Log_event's ctor, this way we can extract maximum information from the
event's header (the unique ID for example).
*/
- Unknown_log_event(const char* buf, const Format_description_log_event* description_event):
+ Unknown_log_event(const char* buf,
+ const Format_description_log_event *description_event):
Log_event(buf, description_event)
{}
~Unknown_log_event() {}
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
Log_event_type get_type_code() { return UNKNOWN_EVENT;}
bool is_valid() const { return 1; }
};
#endif
char *str_to_hex(char *to, const char *from, uint len);
+
+/*****************************************************************************
+
+ Table map log event class
+
+ Create a mapping from a (database name, table name) couple to a table
+ identifier (an integer number).
+
+ ****************************************************************************/
+class Table_map_log_event : public Log_event
+{
+public:
+ /* Constants */
+ enum
+ {
+ TYPE_CODE = TABLE_MAP_EVENT
+ };
+
+ /**
+ Enumeration of the errors that can be returned.
+ */
+ enum enum_error
+ {
+ ERR_OPEN_FAILURE = -1, /**< Failure to open table */
+ ERR_OK = 0, /**< No error */
+ ERR_TABLE_LIMIT_EXCEEDED = 1, /**< No more room for tables */
+ ERR_OUT_OF_MEM = 2, /**< Out of memory */
+ ERR_BAD_TABLE_DEF = 3, /**< Table definition does not match */
+ ERR_RBR_TO_SBR = 4 /**< daisy-chanining RBR to SBR not allowed */
+ };
+
+ enum enum_flag
+ {
+ /*
+ Nothing here right now, but the flags support is there in
+ preparation for changes that are coming. Need to add a
+ constant to make it compile under HP-UX: aCC does not like
+ empty enumerations.
+ */
+ ENUM_FLAG_COUNT
+ };
+
+ typedef uint16 flag_set;
+
+ /* Special constants representing sets of flags */
+ enum
+ {
+ TM_NO_FLAGS = 0U
+ };
+
+ void set_flags(flag_set flag) { m_flags |= flag; }
+ void clear_flags(flag_set flag) { m_flags &= ~flag; }
+ flag_set get_flags(flag_set flag) const { return m_flags & flag; }
+
+#ifndef MYSQL_CLIENT
+ Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
+ bool is_transactional, uint16 flags);
+#endif
+#ifdef HAVE_REPLICATION
+ Table_map_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+
+ ~Table_map_log_event();
+
+ virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
+ virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }
+
+ virtual int get_data_size() { return m_data_size; }
+#ifndef MYSQL_CLIENT
+ virtual int save_field_metadata();
+ virtual bool write_data_header(IO_CACHE *file);
+ virtual bool write_data_body(IO_CACHE *file);
+ virtual const char *get_db() { return m_dbnam; }
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual void pack_info(Protocol *protocol);
+#endif
+
+#ifdef MYSQL_CLIENT
+ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+
+private:
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
+
+#ifndef MYSQL_CLIENT
+ TABLE *m_table;
+#endif
+ char const *m_dbnam;
+ size_t m_dblen;
+ char const *m_tblnam;
+ size_t m_tbllen;
+ ulong m_colcnt;
+ uchar *m_coltype;
+
+ uchar *m_memory;
+ ulong m_table_id;
+ flag_set m_flags;
+
+ size_t m_data_size;
+
+ uchar *m_field_metadata; // buffer for field metadata
+ /*
+ The size of field metadata buffer set by calling save_field_metadata()
+ */
+ ulong m_field_metadata_size;
+ uchar *m_null_bits;
+ uchar *m_meta_memory;
+};
+
+
+/*****************************************************************************
+
+ Row level log event class.
+
+ Common base class for all row-containing log events.
+
+ RESPONSIBILITIES
+
+ Encode the common parts of all events containing rows, which are:
+ - Write data header and data body to an IO_CACHE.
+ - Provide an interface for adding an individual row to the event.
+
+ ****************************************************************************/
+
+
+class Rows_log_event : public Log_event
+{
+public:
+ /**
+ Enumeration of the errors that can be returned.
+ */
+ enum enum_error
+ {
+ ERR_OPEN_FAILURE = -1, /**< Failure to open table */
+ ERR_OK = 0, /**< No error */
+ ERR_TABLE_LIMIT_EXCEEDED = 1, /**< No more room for tables */
+ ERR_OUT_OF_MEM = 2, /**< Out of memory */
+ ERR_BAD_TABLE_DEF = 3, /**< Table definition does not match */
+ ERR_RBR_TO_SBR = 4 /**< daisy-chanining RBR to SBR not allowed */
+ };
+
+ /*
+ These definitions allow you to combine the flags into an
+ appropriate flag set using the normal bitwise operators. The
+ implicit conversion from an enum-constant to an integer is
+ accepted by the compiler, which is then used to set the real set
+ of flags.
+ */
+ enum enum_flag
+ {
+ /* Last event of a statement */
+ STMT_END_F = (1U << 0),
+
+ /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
+ NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
+
+ /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
+ RELAXED_UNIQUE_CHECKS_F = (1U << 2),
+
+ /**
+ Indicates that rows in this event are complete, that is contain
+ values for all columns of the table.
+ */
+ COMPLETE_ROWS_F = (1U << 3)
+ };
+
+ typedef uint16 flag_set;
+
+ /* Special constants representing sets of flags */
+ enum
+ {
+ RLE_NO_FLAGS = 0U
+ };
+
+ virtual ~Rows_log_event();
+
+ void set_flags(flag_set flags_arg) { m_flags |= flags_arg; }
+ 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; }
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual void pack_info(Protocol *protocol);
+#endif
+
+#ifdef MYSQL_CLIENT
+ /* not for direct call, each derived has its own ::print() */
+ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
+#endif
+
+#ifndef MYSQL_CLIENT
+ int add_row_data(uchar *data, size_t length)
+ {
+ return do_add_row_data(data,length);
+ }
+#endif
+
+ /* Member functions to implement superclass interface */
+ virtual int get_data_size();
+
+ MY_BITMAP const *get_cols() const { return &m_cols; }
+ size_t get_width() const { return m_width; }
+ ulong get_table_id() const { return m_table_id; }
+
+#ifndef MYSQL_CLIENT
+ virtual bool write_data_header(IO_CACHE *file);
+ virtual bool write_data_body(IO_CACHE *file);
+ virtual const char *get_db() { return m_table->s->db.str; }
+#endif
+ /*
+ Check that malloc() succeeded in allocating memory for the rows
+ buffer and the COLS vector. Checking that an Update_rows_log_event
+ is valid is done in the Update_rows_log_event::is_valid()
+ function.
+ */
+ virtual bool is_valid() const
+ {
+ return m_rows_buf && m_cols.bitmap;
+ }
+
+ uint m_row_count; /* The number of rows added to the event */
+
+protected:
+ /*
+ The constructors are protected since you're supposed to inherit
+ this class, not create instances of this class.
+ */
+#ifndef MYSQL_CLIENT
+ Rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols, bool is_transactional);
+#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
+ void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
+#endif
+
+#ifndef MYSQL_CLIENT
+ virtual int do_add_row_data(uchar *data, size_t length);
+#endif
+
+#ifndef MYSQL_CLIENT
+ TABLE *m_table; /* The table the rows belong to */
+#endif
+ ulong m_table_id; /* Table ID */
+ MY_BITMAP m_cols; /* Bitmap denoting columns available */
+ ulong m_width; /* The width of the columns bitmap */
+ /*
+ Bitmap for columns available in the after image, if present. These
+ fields are only available for Update_rows events. Observe that the
+ width of both the before image COLS vector and the after image
+ COLS vector is the same: the number of columns of the table on the
+ master.
+ */
+ MY_BITMAP m_cols_ai;
+
+ ulong m_master_reclength; /* Length of record on master side */
+
+ /* Bit buffers in the same memory as the class */
+ uint32 m_bitbuf[128/(sizeof(uint32)*8)];
+ uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)];
+
+ uchar *m_rows_buf; /* The rows in packed format */
+ uchar *m_rows_cur; /* One-after the end of the data */
+ uchar *m_rows_end; /* One-after the end of the allocated space */
+
+ flag_set m_flags; /* Flags for row-level events */
+
+ /* helper functions */
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ const uchar *m_curr_row; /* Start of the row being processed */
+ const uchar *m_curr_row_end; /* One-after the end of the current row */
+ uchar *m_key; /* Buffer to keep key value during searches */
+
+ int find_row(const Relay_log_info *const);
+ int write_row(const Relay_log_info *const, const bool);
+
+ // Unpack the current row into m_table->record[0]
+ int unpack_current_row(const Relay_log_info *const rli)
+ {
+ DBUG_ASSERT(m_table);
+ return ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
+ &m_curr_row_end, &m_master_reclength);
+ }
+#endif
+
+private:
+
+#if !defined(MYSQL_CLIENT) && 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);
+
+ /*
+ Primitive to prepare for a sequence of row executions.
+
+ DESCRIPTION
+
+ Before doing a sequence of do_prepare_row() and do_exec_row()
+ calls, this member function should be called to prepare for the
+ entire sequence. Typically, this member function will allocate
+ space for any buffers that are needed for the two member
+ functions mentioned above.
+
+ RETURN VALUE
+
+ The member function will return 0 if all went OK, or a non-zero
+ error code otherwise.
+ */
+ virtual
+ int do_before_row_operations(const Slave_reporting_capability *const log) = 0;
+
+ /*
+ Primitive to clean up after a sequence of row executions.
+
+ DESCRIPTION
+
+ After doing a sequence of do_prepare_row() and do_exec_row(),
+ this member function should be called to clean up and release
+ any allocated buffers.
+
+ The error argument, if non-zero, indicates an error which happened during
+ row processing before this function was called. In this case, even if
+ function is successful, it should return the error code given in the argument.
+ */
+ virtual
+ int do_after_row_operations(const Slave_reporting_capability *const log,
+ int error) = 0;
+
+ /*
+ Primitive to do the actual execution necessary for a row.
+
+ DESCRIPTION
+ The member function will do the actual execution needed to handle a row.
+ The row is located at m_curr_row. When the function returns,
+ m_curr_row_end should point at the next row (one byte after the end
+ of the current row).
+
+ RETURN VALUE
+ 0 if execution succeeded, 1 if execution failed.
+
+ */
+ virtual int do_exec_row(const Relay_log_info *const rli) = 0;
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+
+ friend class Old_rows_log_event;
+};
+
+/*****************************************************************************
+
+ Write row log event class
+
+ Log row insertions and updates. The event contain several
+ insert/update rows for a table. Note that each event contains only
+ rows for one table.
+
+ ****************************************************************************/
+class Write_rows_log_event : public Rows_log_event
+{
+public:
+ enum
+ {
+ /* Support interface to THD::binlog_prepare_pending_rows_event */
+ TYPE_CODE = WRITE_ROWS_EVENT
+ };
+
+#if !defined(MYSQL_CLIENT)
+ Write_rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols, bool is_transactional);
+#endif
+#ifdef HAVE_REPLICATION
+ Write_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+#if !defined(MYSQL_CLIENT)
+ static bool binlog_row_logging_function(THD *thd, TABLE *table,
+ bool is_transactional,
+ MY_BITMAP *cols,
+ uint fields,
+ const uchar *before_record
+ __attribute__((unused)),
+ const uchar *after_record)
+ {
+ return thd->binlog_write_row(table, is_transactional,
+ cols, fields, after_record);
+ }
+#endif
+
+private:
+ virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+
+#ifdef MYSQL_CLIENT
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
+};
+
+
+/*****************************************************************************
+
+ Update rows log event class
+
+ Log row updates with a before image. The event contain several
+ update rows for a table. Note that each event contains only rows for
+ one table.
+
+ Also note that the row data consists of pairs of row data: one row
+ for the old data and one row for the new data.
+
+ ****************************************************************************/
+class Update_rows_log_event : public Rows_log_event
+{
+public:
+ enum
+ {
+ /* Support interface to THD::binlog_prepare_pending_rows_event */
+ TYPE_CODE = UPDATE_ROWS_EVENT
+ };
+
+#ifndef MYSQL_CLIENT
+ Update_rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols_bi,
+ MY_BITMAP const *cols_ai,
+ bool is_transactional);
+
+ Update_rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols,
+ bool is_transactional);
+
+ void init(MY_BITMAP const *cols);
+#endif
+
+ virtual ~Update_rows_log_event();
+
+#ifdef HAVE_REPLICATION
+ Update_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+
+#if !defined(MYSQL_CLIENT)
+ static bool binlog_row_logging_function(THD *thd, TABLE *table,
+ bool is_transactional,
+ MY_BITMAP *cols,
+ uint fields,
+ const uchar *before_record,
+ const uchar *after_record)
+ {
+ return thd->binlog_update_row(table, is_transactional,
+ cols, fields, before_record, after_record);
+ }
+#endif
+
+ virtual bool is_valid() const
+ {
+ return Rows_log_event::is_valid() && m_cols_ai.bitmap;
+ }
+
+protected:
+ virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+
+#ifdef MYSQL_CLIENT
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && 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);
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+};
+
+/*****************************************************************************
+
+ Delete rows log event class.
+
+ Log row deletions. The event contain several delete rows for a
+ table. Note that each event contains only rows for one table.
+
+ RESPONSIBILITIES
+
+ - Act as a container for rows that has been deleted on the master
+ and should be deleted on the slave.
+
+ COLLABORATION
+
+ Row_writer
+ Create the event and add rows to the event.
+ Row_reader
+ Extract the rows from the event.
+
+ ****************************************************************************/
+class Delete_rows_log_event : public Rows_log_event
+{
+public:
+ enum
+ {
+ /* Support interface to THD::binlog_prepare_pending_rows_event */
+ TYPE_CODE = DELETE_ROWS_EVENT
+ };
+
+#ifndef MYSQL_CLIENT
+ Delete_rows_log_event(THD*, TABLE*, ulong,
+ MY_BITMAP const *cols, bool is_transactional);
+#endif
+#ifdef HAVE_REPLICATION
+ Delete_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+#if !defined(MYSQL_CLIENT)
+ static bool binlog_row_logging_function(THD *thd, TABLE *table,
+ bool is_transactional,
+ MY_BITMAP *cols,
+ uint fields,
+ const uchar *before_record,
+ const uchar *after_record
+ __attribute__((unused)))
+ {
+ return thd->binlog_delete_row(table, is_transactional,
+ cols, fields, before_record);
+ }
+#endif
+
+protected:
+ virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+
+#ifdef MYSQL_CLIENT
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && 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);
+#endif
+};
+
+
+#include "log_event_old.h"
+
+/**
+ Class representing an incident, an occurance out of the ordinary,
+ that happened on the master.
+
+ The event is used to inform the slave that something out of the
+ ordinary happened on the master that might cause the database to be
+ in an inconsistent state.
+
+ <table id="IncidentFormat">
+ <caption>Incident event format</caption>
+ <tr>
+ <th>Symbol</th>
+ <th>Size<br>(bytes)</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>INCIDENT</td>
+ <td align="right">2</td>
+ <td>Incident number as an unsigned integer</td>
+ </tr>
+ <tr>
+ <td>MSGLEN</td>
+ <td align="right">1</td>
+ <td>Message length as an unsigned integer</td>
+ </tr>
+ <tr>
+ <td>MESSAGE</td>
+ <td align="right">MSGLEN</td>
+ <td>The message, if present. Not null terminated.</td>
+ </tr>
+ </table>
+ */
+class Incident_log_event : public Log_event {
+public:
+#ifndef MYSQL_CLIENT
+ Incident_log_event(THD *thd_arg, Incident incident)
+ : Log_event(thd_arg, 0, FALSE), m_incident(incident)
+ {
+ DBUG_ENTER("Incident_log_event::Incident_log_event");
+ DBUG_PRINT("enter", ("m_incident: %d", m_incident));
+ m_message.str= NULL; /* Just as a precaution */
+ m_message.length= 0;
+ DBUG_VOID_RETURN;
+ }
+
+ Incident_log_event(THD *thd_arg, Incident incident, LEX_STRING const msg)
+ : Log_event(thd_arg, 0, FALSE), m_incident(incident)
+ {
+ DBUG_ENTER("Incident_log_event::Incident_log_event");
+ DBUG_PRINT("enter", ("m_incident: %d", m_incident));
+ m_message= msg;
+ DBUG_VOID_RETURN;
+ }
+#endif
+
+#ifndef MYSQL_CLIENT
+ void pack_info(Protocol*);
+#endif
+
+ Incident_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *descr_event);
+
+ virtual ~Incident_log_event();
+
+#ifdef MYSQL_CLIENT
+ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int do_apply_event(Relay_log_info const *rli);
+#endif
+
+ virtual bool write_data_header(IO_CACHE *file);
+ virtual bool write_data_body(IO_CACHE *file);
+
+ virtual Log_event_type get_type_code() { return INCIDENT_EVENT; }
+
+ virtual bool is_valid() const { return 1; }
+ virtual int get_data_size() {
+ return INCIDENT_HEADER_LEN + 1 + m_message.length;
+ }
+
+private:
+ const char *description() const;
+
+ Incident m_incident;
+ LEX_STRING m_message;
+};
+
+static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
+ FILE *file)
+{
+ return
+ my_b_copy_to_file(cache, file) ||
+ reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
+}
+
+/**
+ @} (end of group Replication)
+*/
+
#endif /* _log_event_h */