@@ -305,7 +305,7 @@ class Write_on_release_cache
305305 ~Write_on_release_cache ()
306306 {
307307 copy_event_cache_to_file_and_reinit (m_cache, m_file);
308- if (m_flags | FLUSH_F)
308+ if (m_flags & FLUSH_F)
309309 fflush (m_file);
310310 }
311311
@@ -813,6 +813,15 @@ const char* Log_event::get_type_str(Log_event_type type)
813813 case BINLOG_CHECKPOINT_EVENT: return " Binlog_checkpoint" ;
814814 case GTID_EVENT: return " Gtid" ;
815815 case GTID_LIST_EVENT: return " Gtid_list" ;
816+
817+ /* The following is only for mysqlbinlog */
818+ case IGNORABLE_LOG_EVENT: return " Ignorable log event" ;
819+ case ROWS_QUERY_LOG_EVENT: return " MySQL Rows_query" ;
820+ case GTID_LOG_EVENT: return " MySQL Gtid" ;
821+ case ANONYMOUS_GTID_LOG_EVENT: return " MySQL Anonymous_Gtid" ;
822+ case PREVIOUS_GTIDS_LOG_EVENT: return " MySQL Previous_gtids" ;
823+ case HEARTBEAT_LOG_EVENT: return " Heartbeat" ;
824+
816825 default : return " Unknown" ;/* impossible */
817826 }
818827}
@@ -1416,6 +1425,8 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
14161425 DBUG_ENTER (" Log_event::read_log_event" );
14171426 DBUG_ASSERT (description_event != 0 );
14181427 char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1428+ my_off_t position= my_b_tell (file);
1429+
14191430 /*
14201431 First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
14211432 check the event for sanity and to know its length; no need to really parse
@@ -1427,7 +1438,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
14271438 LOG_EVENT_MINIMAL_HEADER_LEN);
14281439
14291440 LOCK_MUTEX;
1430- DBUG_PRINT (" info" , (" my_b_tell: %lu " , (ulong) my_b_tell (file) ));
1441+ DBUG_PRINT (" info" , (" my_b_tell: %llu " , (ulonglong) position ));
14311442 if (my_b_read (file, (uchar *) head, header_size))
14321443 {
14331444 DBUG_PRINT (" info" , (" Log_event::read_log_event(IO_CACHE*,Format_desc*) \
@@ -1484,8 +1495,9 @@ failed my_b_read"));
14841495 {
14851496 DBUG_ASSERT (error != 0 );
14861497 sql_print_error (" Error in Log_event::read_log_event(): "
1487- " '%s', data_len: %lu, event_type: %d" ,
1488- error,data_len,(uchar)(head[EVENT_TYPE_OFFSET]));
1498+ " '%s' at offset: %llu data_len: %lu event_type: %d" ,
1499+ error, position, data_len,
1500+ (uchar)(head[EVENT_TYPE_OFFSET]));
14891501 my_free (buf);
14901502 /*
14911503 The SQL slave thread will check if file->error<0 to know
@@ -1518,10 +1530,12 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
15181530 DBUG_PRINT (" info" , (" binlog_version: %d" , description_event->binlog_version ));
15191531 DBUG_DUMP (" data" , (unsigned char *) buf, event_len);
15201532
1521- /* Check the integrity */
1533+ /*
1534+ Check the integrity; This is needed because handle_slave_io() doesn't
1535+ check if packet is of proper length.
1536+ */
15221537 if (event_len < EVENT_LEN_OFFSET ||
1523- (uchar)buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
1524- (uint) event_len != uint4korr (buf+EVENT_LEN_OFFSET))
1538+ event_len != uint4korr (buf+EVENT_LEN_OFFSET))
15251539 {
15261540 *error=" Sanity check failed" ;// Needed to free buffer
15271541 DBUG_RETURN (NULL ); // general sanity check - will fail on a partial read
@@ -1703,6 +1717,15 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
17031717 case DELETE_ROWS_EVENT:
17041718 ev = new Delete_rows_log_event (buf, event_len, description_event);
17051719 break ;
1720+
1721+ /* MySQL GTID events are ignored */
1722+ case GTID_LOG_EVENT:
1723+ case ANONYMOUS_GTID_LOG_EVENT:
1724+ case PREVIOUS_GTIDS_LOG_EVENT:
1725+ ev= new Ignorable_log_event (buf, description_event,
1726+ get_type_str ((Log_event_type) event_type));
1727+ break ;
1728+
17061729 case TABLE_MAP_EVENT:
17071730 ev = new Table_map_log_event (buf, event_len, description_event);
17081731 break ;
@@ -1720,10 +1743,22 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
17201743 ev = new Annotate_rows_log_event (buf, event_len, description_event);
17211744 break ;
17221745 default :
1723- DBUG_PRINT (" error" ,(" Unknown event code: %d" ,
1724- (int ) buf[EVENT_TYPE_OFFSET]));
1725- ev= NULL ;
1726- break ;
1746+ /*
1747+ Create an object of Ignorable_log_event for unrecognized sub-class.
1748+ So that SLAVE SQL THREAD will only update the position and continue.
1749+ */
1750+ if (uint2korr (buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
1751+ {
1752+ ev= new Ignorable_log_event (buf, description_event,
1753+ get_type_str ((Log_event_type) event_type));
1754+ }
1755+ else
1756+ {
1757+ DBUG_PRINT (" error" ,(" Unknown event code: %d" ,
1758+ (int ) buf[EVENT_TYPE_OFFSET]));
1759+ ev= NULL ;
1760+ break ;
1761+ }
17271762 }
17281763 }
17291764
@@ -4891,6 +4926,9 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
48914926 post_header_len[HEARTBEAT_LOG_EVENT-1 ]= 0 ;
48924927 post_header_len[IGNORABLE_LOG_EVENT-1 ]= 0 ;
48934928 post_header_len[ROWS_QUERY_LOG_EVENT-1 ]= 0 ;
4929+ post_header_len[GTID_LOG_EVENT-1 ]= 0 ;
4930+ post_header_len[ANONYMOUS_GTID_LOG_EVENT-1 ]= 0 ;
4931+ post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1 ]= 0 ;
48944932 post_header_len[WRITE_ROWS_EVENT-1 ]= ROWS_HEADER_LEN_V2;
48954933 post_header_len[UPDATE_ROWS_EVENT-1 ]= ROWS_HEADER_LEN_V2;
48964934 post_header_len[DELETE_ROWS_EVENT-1 ]= ROWS_HEADER_LEN_V2;
@@ -12639,6 +12677,52 @@ Incident_log_event::write_data_body(IO_CACHE *file)
1263912677}
1264012678
1264112679
12680+ Ignorable_log_event::Ignorable_log_event (const char *buf,
12681+ const Format_description_log_event
12682+ *descr_event,
12683+ const char *event_name)
12684+ :Log_event(buf, descr_event), number((int ) (uchar) buf[EVENT_TYPE_OFFSET]),
12685+ description(event_name)
12686+ {
12687+ DBUG_ENTER (" Ignorable_log_event::Ignorable_log_event" );
12688+ DBUG_VOID_RETURN;
12689+ }
12690+
12691+ Ignorable_log_event::~Ignorable_log_event ()
12692+ {
12693+ }
12694+
12695+ #ifndef MYSQL_CLIENT
12696+ /* Pack info for its unrecognized ignorable event */
12697+ void Ignorable_log_event::pack_info (THD *thd, Protocol *protocol)
12698+ {
12699+ char buf[256 ];
12700+ size_t bytes;
12701+ bytes= my_snprintf (buf, sizeof (buf), " # Ignorable event type %d (%s)" ,
12702+ number, description);
12703+ protocol->store (buf, bytes, &my_charset_bin);
12704+ }
12705+ #endif
12706+
12707+ #ifdef MYSQL_CLIENT
12708+ /* Print for its unrecognized ignorable event */
12709+ void
12710+ Ignorable_log_event::print (FILE *file,
12711+ PRINT_EVENT_INFO *print_event_info)
12712+ {
12713+ if (print_event_info->short_form )
12714+ return ;
12715+
12716+ print_header (&print_event_info->head_cache , print_event_info, FALSE );
12717+ my_b_printf (&print_event_info->head_cache , " \t Ignorable\n " );
12718+ my_b_printf (&print_event_info->head_cache ,
12719+ " # Ignorable event type %d (%s)\n " , number, description);
12720+ copy_event_cache_to_file_and_reinit (&print_event_info->head_cache ,
12721+ file);
12722+ }
12723+ #endif
12724+
12725+
1264212726#ifdef MYSQL_CLIENT
1264312727/* *
1264412728 The default values for these variables should be values that are
@@ -12720,4 +12804,25 @@ bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos,
1272012804 return TRUE ;
1272112805#endif
1272212806}
12807+
12808+ /* *
12809+ Check if we should write event to the relay log
12810+
12811+ This is used to skip events that is only supported by MySQL
12812+
12813+ Return:
12814+ 0 ok
12815+ 1 Don't write event
12816+ */
12817+
12818+ bool event_that_should_be_ignored (const char *buf)
12819+ {
12820+ uint event_type= (uchar)buf[EVENT_TYPE_OFFSET];
12821+ if (event_type == GTID_LOG_EVENT ||
12822+ event_type == ANONYMOUS_GTID_LOG_EVENT ||
12823+ event_type == PREVIOUS_GTIDS_LOG_EVENT ||
12824+ (uint2korr (buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F))
12825+ return 1 ;
12826+ return 0 ;
12827+ }
1272312828#endif
0 commit comments