Add LOAD DATA INFILE support

The events are similar to normal query events except that they have an
extra 13 bytes of static data. This data is of no relevance to Maxscale
and thus can be ignored. This also allows the reuse of the same query
event code for execute load query events.
This commit is contained in:
Markus Mäkelä
2019-12-16 11:07:14 +02:00
parent a1009824a6
commit be088c54b4
2 changed files with 16 additions and 7 deletions

View File

@ -303,6 +303,7 @@ bool BinlogFilterSession::checkEvent(GWBUF** buffer, const REP_HEADER& hdr)
} }
else else
{ {
int extra_bytes = 0;
// Current event size is less than MYSQL_PACKET_LENGTH_MAX // Current event size is less than MYSQL_PACKET_LENGTH_MAX
// or is the beginning of large event. // or is the beginning of large event.
switch (hdr.event_type) switch (hdr.event_type)
@ -342,9 +343,14 @@ bool BinlogFilterSession::checkEvent(GWBUF** buffer, const REP_HEADER& hdr)
skipDatabaseTable(body); skipDatabaseTable(body);
break; 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: case QUERY_EVENT:
// Handle the SQL statement: DDL, DML, BEGIN, COMMIT // 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 // checkStatement can reallocate the buffer in case the size changes: use fresh pointers
fixEvent(GWBUF_DATA(*buffer) + MYSQL_HEADER_LEN + 1, 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 * 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. * be rewritten. If a rewrite takes place, the buffer can be reallocated.
* *
* @param bufer Pointer to the buffer containing the event * @param bufer Pointer to the buffer containing the event
* @param hdr The extracted replication header * @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; 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; 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 db_name_len = event[4 + 4];
int var_block_len_offset = 4 + 4 + 1 + 2; int var_block_len_offset = 4 + 4 + 1 + 2;
int var_block_len = gw_mysql_get_byte2(event + var_block_len_offset); 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); 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); std::string db((char*)event + static_size + var_block_len, db_name_len);

View File

@ -22,6 +22,8 @@
#define RAND_EVENT 0x000D #define RAND_EVENT 0x000D
#define TABLE_MAP_EVENT 0x0013 #define TABLE_MAP_EVENT 0x0013
#define XID_EVENT 0x0010 #define XID_EVENT 0x0010
#define BEGIN_LOAD_QUERY_EVENT 0x0011
#define EXECUTE_LOAD_QUERY_EVENT 0x0012
#define QUERY_EVENT 0x0002 #define QUERY_EVENT 0x0002
#define MARIADB10_GTID_EVENT 0x00a2 #define MARIADB10_GTID_EVENT 0x00a2
#define MARIADB_ANNOTATE_ROWS_EVENT 0x00a0 #define MARIADB_ANNOTATE_ROWS_EVENT 0x00a0
@ -99,8 +101,8 @@ private:
// Handle event data // Handle event data
void handleEventData(uint32_t len); void handleEventData(uint32_t len);
// Check SQL statement in QUERY_EVENT // Check SQL statement in QUERY_EVENT or EXECUTE_LOAD_QUERY_EVENT
void checkStatement(GWBUF** buffer, const REP_HEADER& hdr); void checkStatement(GWBUF** buffer, const REP_HEADER& hdr, int extra_len = 0);
// Check DB.TABLE in ANNOTATE_ROWS event // Check DB.TABLE in ANNOTATE_ROWS event
void checkAnnotate(const uint8_t* event, void checkAnnotate(const uint8_t* event,