summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@mariadb.com>2015-10-31 18:07:02 -0400
committerNirbhay Choubey <nirbhay@mariadb.com>2015-10-31 18:07:02 -0400
commit4d1511296288782df0e3d9373396724e250b24c1 (patch)
tree9fa47d141b71933859d6c2da585e5bb5e52db212 /sql/log_event.cc
parent17b0b45b1de41a1b188c5de6c3e9d8e6ecc48a72 (diff)
parentd775ecdd010daad4dc6147fba58acd006bf2c60c (diff)
downloadmariadb-git-4d1511296288782df0e3d9373396724e250b24c1.tar.gz
Merge tag 'mariadb-10.0.22' into 10.0-galera
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc142
1 files changed, 120 insertions, 22 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index f50bb3d8b81..a1dcce7d7c4 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -308,7 +308,7 @@ public:
~Write_on_release_cache()
{
copy_event_cache_to_file_and_reinit(m_cache, m_file);
- if (m_flags | FLUSH_F)
+ if (m_flags & FLUSH_F)
fflush(m_file);
}
@@ -816,6 +816,15 @@ const char* Log_event::get_type_str(Log_event_type type)
case BINLOG_CHECKPOINT_EVENT: return "Binlog_checkpoint";
case GTID_EVENT: return "Gtid";
case GTID_LIST_EVENT: return "Gtid_list";
+
+ /* The following is only for mysqlbinlog */
+ case IGNORABLE_LOG_EVENT: return "Ignorable log event";
+ case ROWS_QUERY_LOG_EVENT: return "MySQL Rows_query";
+ case GTID_LOG_EVENT: return "MySQL Gtid";
+ case ANONYMOUS_GTID_LOG_EVENT: return "MySQL Anonymous_Gtid";
+ case PREVIOUS_GTIDS_LOG_EVENT: return "MySQL Previous_gtids";
+ case HEARTBEAT_LOG_EVENT: return "Heartbeat";
+
default: return "Unknown"; /* impossible */
}
}
@@ -1419,6 +1428,8 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
DBUG_ENTER("Log_event::read_log_event");
DBUG_ASSERT(description_event != 0);
char head[LOG_EVENT_MINIMAL_HEADER_LEN];
+ my_off_t position= my_b_tell(file);
+
/*
First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
check the event for sanity and to know its length; no need to really parse
@@ -1430,7 +1441,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
LOG_EVENT_MINIMAL_HEADER_LEN);
LOCK_MUTEX;
- DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
+ DBUG_PRINT("info", ("my_b_tell: %llu", (ulonglong) position));
if (my_b_read(file, (uchar *) head, header_size))
{
DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \
@@ -1487,8 +1498,9 @@ err:
{
DBUG_ASSERT(error != 0);
sql_print_error("Error in Log_event::read_log_event(): "
- "'%s', data_len: %lu, event_type: %d",
- error,data_len,(uchar)(head[EVENT_TYPE_OFFSET]));
+ "'%s' at offset: %llu data_len: %lu event_type: %d",
+ error, position, data_len,
+ (uchar)(head[EVENT_TYPE_OFFSET]));
my_free(buf);
/*
The SQL slave thread will check if file->error<0 to know
@@ -1521,10 +1533,12 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
DBUG_DUMP("data", (unsigned char*) buf, event_len);
- /* Check the integrity */
+ /*
+ Check the integrity; This is needed because handle_slave_io() doesn't
+ check if packet is of proper length.
+ */
if (event_len < EVENT_LEN_OFFSET ||
- (uchar)buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
- (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
+ event_len != uint4korr(buf+EVENT_LEN_OFFSET))
{
*error="Sanity check failed"; // Needed to free buffer
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
@@ -1706,6 +1720,15 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
case DELETE_ROWS_EVENT:
ev = new Delete_rows_log_event(buf, event_len, description_event);
break;
+
+ /* MySQL GTID events are ignored */
+ case GTID_LOG_EVENT:
+ case ANONYMOUS_GTID_LOG_EVENT:
+ case PREVIOUS_GTIDS_LOG_EVENT:
+ ev= new Ignorable_log_event(buf, description_event,
+ get_type_str((Log_event_type) event_type));
+ break;
+
case TABLE_MAP_EVENT:
ev = new Table_map_log_event(buf, event_len, description_event);
break;
@@ -1723,10 +1746,22 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
ev = new Annotate_rows_log_event(buf, event_len, description_event);
break;
default:
- DBUG_PRINT("error",("Unknown event code: %d",
- (int) buf[EVENT_TYPE_OFFSET]));
- ev= NULL;
- break;
+ /*
+ Create an object of Ignorable_log_event for unrecognized sub-class.
+ So that SLAVE SQL THREAD will only update the position and continue.
+ */
+ if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
+ {
+ ev= new Ignorable_log_event(buf, description_event,
+ get_type_str((Log_event_type) event_type));
+ }
+ else
+ {
+ DBUG_PRINT("error",("Unknown event code: %d",
+ (int) buf[EVENT_TYPE_OFFSET]));
+ ev= NULL;
+ break;
+ }
}
}
@@ -2192,20 +2227,13 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
uint precision= meta >> 8;
uint decimals= meta & 0xFF;
uint bin_size= my_decimal_get_binary_size(precision, decimals);
- uint length;
my_decimal dec;
binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
precision, decimals);
- int i, end;
- char buff[512], *pos;
- pos= buff;
- pos+= sprintf(buff, "%s", dec.sign() ? "-" : "");
- end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1;
- for (i=0; i < end; i++)
- pos+= sprintf(pos, "%09d.", dec.buf[i]);
- pos+= sprintf(pos, "%09d", dec.buf[i]);
- length= (uint) (pos - buff);
- my_b_write(file, buff, length);
+ int length= DECIMAL_MAX_STR_LENGTH;
+ char buff[DECIMAL_MAX_STR_LENGTH + 1];
+ decimal2string(&dec, buff, &length, 0, 0, 0);
+ my_b_write(file, (uchar*)buff, length);
my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
precision, decimals);
return bin_size;
@@ -4920,6 +4948,9 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
post_header_len[IGNORABLE_LOG_EVENT-1]= 0;
post_header_len[ROWS_QUERY_LOG_EVENT-1]= 0;
+ post_header_len[GTID_LOG_EVENT-1]= 0;
+ post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]= 0;
+ post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= 0;
post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
@@ -12835,6 +12866,52 @@ Incident_log_event::write_data_body(IO_CACHE *file)
}
+Ignorable_log_event::Ignorable_log_event(const char *buf,
+ const Format_description_log_event
+ *descr_event,
+ const char *event_name)
+ :Log_event(buf, descr_event), number((int) (uchar) buf[EVENT_TYPE_OFFSET]),
+ description(event_name)
+{
+ DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
+ DBUG_VOID_RETURN;
+}
+
+Ignorable_log_event::~Ignorable_log_event()
+{
+}
+
+#ifndef MYSQL_CLIENT
+/* Pack info for its unrecognized ignorable event */
+void Ignorable_log_event::pack_info(THD *thd, Protocol *protocol)
+{
+ char buf[256];
+ size_t bytes;
+ bytes= my_snprintf(buf, sizeof(buf), "# Ignorable event type %d (%s)",
+ number, description);
+ protocol->store(buf, bytes, &my_charset_bin);
+}
+#endif
+
+#ifdef MYSQL_CLIENT
+/* Print for its unrecognized ignorable event */
+void
+Ignorable_log_event::print(FILE *file,
+ PRINT_EVENT_INFO *print_event_info)
+{
+ if (print_event_info->short_form)
+ return;
+
+ print_header(&print_event_info->head_cache, print_event_info, FALSE);
+ my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
+ my_b_printf(&print_event_info->head_cache,
+ "# Ignorable event type %d (%s)\n", number, description);
+ copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
+ file);
+}
+#endif
+
+
#ifdef MYSQL_CLIENT
/**
The default values for these variables should be values that are
@@ -12916,4 +12993,25 @@ bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos,
return TRUE;
#endif
}
+
+/**
+ Check if we should write event to the relay log
+
+ This is used to skip events that is only supported by MySQL
+
+ Return:
+ 0 ok
+ 1 Don't write event
+*/
+
+bool event_that_should_be_ignored(const char *buf)
+{
+ uint event_type= (uchar)buf[EVENT_TYPE_OFFSET];
+ if (event_type == GTID_LOG_EVENT ||
+ event_type == ANONYMOUS_GTID_LOG_EVENT ||
+ event_type == PREVIOUS_GTIDS_LOG_EVENT ||
+ (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F))
+ return 1;
+ return 0;
+}
#endif