diff --git a/sql/log_event.cc b/sql/log_event.cc index f0b4ca5f8fc..83789400924 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4236,8 +4236,19 @@ Query_log_event::do_shall_skip(Relay_log_info *rli) bool Query_log_event::peek_is_commit_rollback(const char *event_start, - size_t event_len) + size_t event_len, uint8 checksum_alg) { + if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32) + { + if (event_len > BINLOG_CHECKSUM_LEN) + event_len-= BINLOG_CHECKSUM_LEN; + else + event_len= 0; + } + else + DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF || + checksum_alg == BINLOG_CHECKSUM_ALG_OFF); + if (event_len < LOG_EVENT_HEADER_LEN + QUERY_HEADER_LEN || event_len < 9) return false; return !memcmp(event_start + (event_len-7), "\0COMMIT", 7) || @@ -6050,10 +6061,23 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg, */ bool Gtid_log_event::peek(const char *event_start, size_t event_len, + uint8 checksum_alg, uint32 *domain_id, uint32 *server_id, uint64 *seq_no, uchar *flags2) { const char *p; + + if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32) + { + if (event_len > BINLOG_CHECKSUM_LEN) + event_len-= BINLOG_CHECKSUM_LEN; + else + event_len= 0; + } + else + DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF || + checksum_alg == BINLOG_CHECKSUM_ALG_OFF); + if (event_len < LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN) return true; *server_id= uint4korr(event_start + SERVER_ID_OFFSET); diff --git a/sql/log_event.h b/sql/log_event.h index 1c2b2769915..5026b280b27 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1946,7 +1946,7 @@ public: /* !!! Public in this patch to allow old usage */ const char *query_arg, uint32 q_len_arg); static bool peek_is_commit_rollback(const char *event_start, - size_t event_len); + 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 @@ -3084,6 +3084,7 @@ public: 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); #endif diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 550b78832ae..f5f503b9fc8 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1160,7 +1160,8 @@ gtid_state_from_pos(const char *name, uint32 offset, { rpl_gtid gtid; uchar flags2; - if (Gtid_log_event::peek(packet.ptr(), packet.length(), >id.domain_id, + if (Gtid_log_event::peek(packet.ptr(), packet.length(), + current_checksum_alg, >id.domain_id, >id.server_id, >id.seq_no, &flags2)) { errormsg= "Corrupt gtid_log_event found while scanning binlog to find " @@ -1253,6 +1254,7 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, if (ev_offset > len || Gtid_log_event::peek(packet->ptr()+ev_offset, len - ev_offset, + current_checksum_alg, &domain_id, &server_id, &seq_no, &flags2)) return "Failed to read Gtid_log_event: corrupt binlog"; gtid= gtid_state->find(domain_id); @@ -1287,7 +1289,8 @@ send_event_to_slave(THD *thd, NET *net, String* const packet, ushort flags, if (event_type == XID_EVENT || (event_type == QUERY_EVENT && Query_log_event::peek_is_commit_rollback(packet->ptr() + ev_offset, - len - ev_offset))) + len - ev_offset, + current_checksum_alg))) *gtid_skip_group= GTID_SKIP_NOT; return NULL; case GTID_SKIP_NOT: