@@ -305,7 +305,7 @@ class Write_on_release_cache
305
305
~Write_on_release_cache ()
306
306
{
307
307
copy_event_cache_to_file_and_reinit (m_cache, m_file);
308
- if (m_flags | FLUSH_F)
308
+ if (m_flags & FLUSH_F)
309
309
fflush (m_file);
310
310
}
311
311
@@ -813,6 +813,15 @@ const char* Log_event::get_type_str(Log_event_type type)
813
813
case BINLOG_CHECKPOINT_EVENT: return " Binlog_checkpoint" ;
814
814
case GTID_EVENT: return " Gtid" ;
815
815
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
+
816
825
default : return " Unknown" ; /* impossible */
817
826
}
818
827
}
@@ -1416,6 +1425,8 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
1416
1425
DBUG_ENTER (" Log_event::read_log_event" );
1417
1426
DBUG_ASSERT (description_event != 0 );
1418
1427
char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1428
+ my_off_t position= my_b_tell (file);
1429
+
1419
1430
/*
1420
1431
First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
1421
1432
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,
1427
1438
LOG_EVENT_MINIMAL_HEADER_LEN);
1428
1439
1429
1440
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 ));
1431
1442
if (my_b_read (file, (uchar *) head, header_size))
1432
1443
{
1433
1444
DBUG_PRINT (" info" , (" Log_event::read_log_event(IO_CACHE*,Format_desc*) \
@@ -1484,8 +1495,9 @@ failed my_b_read"));
1484
1495
{
1485
1496
DBUG_ASSERT (error != 0 );
1486
1497
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]));
1489
1501
my_free (buf);
1490
1502
/*
1491
1503
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,
1518
1530
DBUG_PRINT (" info" , (" binlog_version: %d" , description_event->binlog_version ));
1519
1531
DBUG_DUMP (" data" , (unsigned char *) buf, event_len);
1520
1532
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
+ */
1522
1537
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))
1525
1539
{
1526
1540
*error=" Sanity check failed" ; // Needed to free buffer
1527
1541
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,
1703
1717
case DELETE_ROWS_EVENT:
1704
1718
ev = new Delete_rows_log_event (buf, event_len, description_event);
1705
1719
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
+
1706
1729
case TABLE_MAP_EVENT:
1707
1730
ev = new Table_map_log_event (buf, event_len, description_event);
1708
1731
break ;
@@ -1720,10 +1743,22 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1720
1743
ev = new Annotate_rows_log_event (buf, event_len, description_event);
1721
1744
break ;
1722
1745
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
+ }
1727
1762
}
1728
1763
}
1729
1764
@@ -4891,6 +4926,9 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
4891
4926
post_header_len[HEARTBEAT_LOG_EVENT-1 ]= 0 ;
4892
4927
post_header_len[IGNORABLE_LOG_EVENT-1 ]= 0 ;
4893
4928
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 ;
4894
4932
post_header_len[WRITE_ROWS_EVENT-1 ]= ROWS_HEADER_LEN_V2;
4895
4933
post_header_len[UPDATE_ROWS_EVENT-1 ]= ROWS_HEADER_LEN_V2;
4896
4934
post_header_len[DELETE_ROWS_EVENT-1 ]= ROWS_HEADER_LEN_V2;
@@ -12639,6 +12677,52 @@ Incident_log_event::write_data_body(IO_CACHE *file)
12639
12677
}
12640
12678
12641
12679
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
+
12642
12726
#ifdef MYSQL_CLIENT
12643
12727
/* *
12644
12728
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,
12720
12804
return TRUE ;
12721
12805
#endif
12722
12806
}
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
+ }
12723
12828
#endif
0 commit comments