From abddf0b0af6c20ca89e9085c1dc3bea9d2ac580f Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Wed, 22 Jun 2022 16:25:37 +0200 Subject: [PATCH] Fixed ROTATE_EVENT If timestamp is zero and flag LOG_EVEBNT_ARTIFICIAL_F was set the event is a fake ROTATE_EVENT (https://mariadb.com/kb/en/fake-rotate_event/) and needs different handling: - a checksum might follow if @@binlog_checksum was set (CRC32) - length calculation is different --- include/mariadb_rpl.h | 1 + libmariadb/mariadb_rpl.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/include/mariadb_rpl.h b/include/mariadb_rpl.h index 0f7b948e..f3e39894 100644 --- a/include/mariadb_rpl.h +++ b/include/mariadb_rpl.h @@ -155,6 +155,7 @@ typedef struct st_mariadb_rpl { uint32_t flags; uint8_t fd_header_len; /* header len from last format description event */ uint8_t use_checksum; + uint8_t artificial_checksun; } MARIADB_RPL; /* Event header */ diff --git a/libmariadb/mariadb_rpl.c b/libmariadb/mariadb_rpl.c index 23ca4635..679db345 100644 --- a/libmariadb/mariadb_rpl.c +++ b/libmariadb/mariadb_rpl.c @@ -67,6 +67,21 @@ MARIADB_RPL * STDCALL mariadb_rpl_init_ex(MYSQL *mysql, unsigned int version) } rpl->version= version; rpl->mysql= mysql; + + if (!mysql_query(mysql, "select @@binlog_checksum")) + { + MYSQL_RES *result; + if ((result= mysql_store_result(mysql))) + { + MYSQL_ROW row= mysql_fetch_row(result); + if (!strcmp(row[0], "CRC32")) + { + rpl->artificial_checksun= 1; + } + mysql_free_result(result); + } + } + return rpl; } @@ -378,8 +393,23 @@ MARIADB_RPL_EVENT * STDCALL mariadb_rpl_fetch(MARIADB_RPL *rpl, MARIADB_RPL_EVEN break; case ROTATE_EVENT: rpl_event->event.rotate.position= uint8korr(ev); - len= rpl_event->event_length - (ev - rpl->mysql->net.read_pos) - 8; ev+= 8; + if (rpl_event->timestamp == 0 && + rpl_event->flags & LOG_EVENT_ARTIFICIAL_F) + { + const uint8_t header_size= 19; + len= rpl_event->event_length - header_size - 8; + if (rpl->artificial_checksun) + { + len-= 4; + int4store(ev + len, rpl_event->checksum); + rpl->artificial_checksun= 0; + } + } + else + { + len= rpl_event->event_length - (ev - rpl->mysql->net.read_pos) - 1; + } if (rpl_alloc_string(rpl_event, &rpl_event->event.rotate.filename, ev, len) || ma_set_rpl_filename(rpl, ev, len)) goto mem_error;