diff --git a/server/modules/filter/binlogfilter/binlogfiltersession.cc b/server/modules/filter/binlogfilter/binlogfiltersession.cc index 33cac4618..08770dc6b 100644 --- a/server/modules/filter/binlogfilter/binlogfiltersession.cc +++ b/server/modules/filter/binlogfilter/binlogfiltersession.cc @@ -303,6 +303,7 @@ bool BinlogFilterSession::checkEvent(GWBUF** buffer, const REP_HEADER& hdr) } else { + int extra_bytes = 0; // Current event size is less than MYSQL_PACKET_LENGTH_MAX // or is the beginning of large event. switch (hdr.event_type) @@ -342,9 +343,14 @@ bool BinlogFilterSession::checkEvent(GWBUF** buffer, const REP_HEADER& hdr) skipDatabaseTable(body); break; + case EXECUTE_LOAD_QUERY_EVENT: + // EXECUTE_LOAD_QUERY_EVENT has an extra 13 bytes of data (file ID, file offset etc.) + extra_bytes = 4 + 4 + 4 + 1; + /** Fallthrough */ + case QUERY_EVENT: // Handle the SQL statement: DDL, DML, BEGIN, COMMIT - checkStatement(buffer, hdr); + checkStatement(buffer, hdr, extra_bytes); // checkStatement can reallocate the buffer in case the size changes: use fresh pointers fixEvent(GWBUF_DATA(*buffer) + MYSQL_HEADER_LEN + 1, @@ -828,10 +834,11 @@ void BinlogFilterSession::handleEventData(uint32_t len) * This function checks whether the statement should be replicated and whether the database/table name should * be rewritten. If a rewrite takes place, the buffer can be reallocated. * - * @param bufer Pointer to the buffer containing the event - * @param hdr The extracted replication header + * @param bufer Pointer to the buffer containing the event + * @param hdr The extracted replication header + * @param extra_len Extra static bytes that this event has (only EXECUTE_LOAD_QUERY_EVENT uses it) */ -void BinlogFilterSession::checkStatement(GWBUF** buffer, const REP_HEADER& hdr) +void BinlogFilterSession::checkStatement(GWBUF** buffer, const REP_HEADER& hdr, int extra_len) { uint8_t* event = GWBUF_DATA(*buffer) + MYSQL_HEADER_LEN + 1 + BINLOG_EVENT_HDR_LEN; uint32_t event_size = hdr.event_size - BINLOG_EVENT_HDR_LEN; @@ -839,7 +846,7 @@ void BinlogFilterSession::checkStatement(GWBUF** buffer, const REP_HEADER& hdr) int db_name_len = event[4 + 4]; int var_block_len_offset = 4 + 4 + 1 + 2; int var_block_len = gw_mysql_get_byte2(event + var_block_len_offset); - int static_size = 4 + 4 + 1 + 2 + 2; + int static_size = 4 + 4 + 1 + 2 + 2 + extra_len; int statement_len = event_size - static_size - var_block_len - db_name_len - 1 - (m_crc ? 4 : 0); std::string db((char*)event + static_size + var_block_len, db_name_len); diff --git a/server/modules/filter/binlogfilter/binlogfiltersession.hh b/server/modules/filter/binlogfilter/binlogfiltersession.hh index acd386107..2b53ca2e0 100644 --- a/server/modules/filter/binlogfilter/binlogfiltersession.hh +++ b/server/modules/filter/binlogfilter/binlogfiltersession.hh @@ -22,6 +22,8 @@ #define RAND_EVENT 0x000D #define TABLE_MAP_EVENT 0x0013 #define XID_EVENT 0x0010 +#define BEGIN_LOAD_QUERY_EVENT 0x0011 +#define EXECUTE_LOAD_QUERY_EVENT 0x0012 #define QUERY_EVENT 0x0002 #define MARIADB10_GTID_EVENT 0x00a2 #define MARIADB_ANNOTATE_ROWS_EVENT 0x00a0 @@ -99,8 +101,8 @@ private: // Handle event data void handleEventData(uint32_t len); - // Check SQL statement in QUERY_EVENT - void checkStatement(GWBUF** buffer, const REP_HEADER& hdr); + // Check SQL statement in QUERY_EVENT or EXECUTE_LOAD_QUERY_EVENT + void checkStatement(GWBUF** buffer, const REP_HEADER& hdr, int extra_len = 0); // Check DB.TABLE in ANNOTATE_ROWS event void checkAnnotate(const uint8_t* event,