diff --git a/libmariadb/mariadb_rpl.c b/libmariadb/mariadb_rpl.c index 4cc09e75..d10c9c8b 100644 --- a/libmariadb/mariadb_rpl.c +++ b/libmariadb/mariadb_rpl.c @@ -112,6 +112,18 @@ int STDCALL mariadb_rpl_open(MARIADB_RPL *rpl) return 0; } +static int ma_set_rpl_filename(MARIADB_RPL *rpl, const unsigned char *filename, size_t len) +{ + if (!rpl) + return 1; + free(rpl->filename); + if (!(rpl->filename= (char *)malloc(len))) + return 1; + memcpy(rpl->filename, filename, len); + rpl->filename_length= len; + return 0; +} + MARIADB_RPL_EVENT * STDCALL mariadb_rpl_fetch(MARIADB_RPL *rpl, MARIADB_RPL_EVENT *event) { unsigned char *ev; @@ -207,13 +219,9 @@ MARIADB_RPL_EVENT * STDCALL mariadb_rpl_fetch(MARIADB_RPL *rpl, MARIADB_RPL_EVEN case BINLOG_CHECKPOINT_EVENT: len= uint4korr(ev); ev+= 4; - if (rpl_alloc_string(rpl_event, &rpl_event->event.checkpoint.filename, ev, len)) + if (rpl_alloc_string(rpl_event, &rpl_event->event.checkpoint.filename, ev, len) || + ma_set_rpl_filename(rpl, ev, len)) goto mem_error; - free(rpl->filename); - if (!(rpl->filename= (char *)malloc(len))) - goto mem_error; - memcpy(rpl->filename, ev, len); - rpl->filename_length= len; break; case FORMAT_DESCRIPTION_EVENT: rpl_event->event.format_description.format = uint2korr(ev); @@ -321,9 +329,10 @@ 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; - len= rpl_event->event_length - rpl->fd_header_len - 8; - if (rpl_alloc_string(rpl_event, &rpl_event->event.rotate.filename, ev, len)) + if (rpl_alloc_string(rpl_event, &rpl_event->event.rotate.filename, ev, len) || + ma_set_rpl_filename(rpl, ev, len)) goto mem_error; break; case XID_EVENT: diff --git a/unittest/libmariadb/rpl_api.c b/unittest/libmariadb/rpl_api.c index 281f15a0..e8414dba 100644 --- a/unittest/libmariadb/rpl_api.c +++ b/unittest/libmariadb/rpl_api.c @@ -163,9 +163,88 @@ static int test_rpl_semisync(MYSQL *my __attribute__((unused))) return OK; } +static int test_conc467(MYSQL *my __attribute__((unused))) +{ + MYSQL *mysql= mysql_init(NULL); + MYSQL_RES *result; + MYSQL_ROW row; + MARIADB_RPL_EVENT *event= NULL; + MARIADB_RPL *rpl; + int rc; + + SKIP_SKYSQL; + SKIP_MAXSCALE; + + if (!is_mariadb) + return SKIP; + + if (!my_test_connect(mysql, hostname, username, + password, schema, port, socketname, 0)) + { + diag("Error: %s", mysql_error(mysql)); + mysql_close(mysql); + return FAIL; + } + + rc= mysql_query(mysql, "SELECT @@log_bin"); + check_mysql_rc(rc, mysql); + + result= mysql_store_result(mysql); + row= mysql_fetch_row(result); + if (!atoi(row[0])) + rc= SKIP; + mysql_free_result(result); + + if (rc == SKIP) + { + diag("binary log disabled -> skip"); + mysql_close(mysql); + return SKIP; + } + + /* Force to create a log rotate event */ + rc= mysql_query(mysql, "FLUSH logs"); + check_mysql_rc(rc, mysql); + + rpl = mariadb_rpl_init(mysql); + + mysql_query(mysql, "SET @mariadb_slave_capability=4"); + mysql_query(mysql, "SET NAMES latin1"); + mysql_query(mysql, "SET @slave_gtid_strict_mode=1"); + mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1"); + mysql_query(mysql, "SET NAMES utf8"); + mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum"); + mysql_query(mysql, "SET @rpl_semi_sync_slave=1"); + rpl->server_id= 12; + rpl->start_position= 4; + rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS; + + if (mariadb_rpl_open(rpl)) + return FAIL; + + if (!(event= mariadb_rpl_fetch(rpl, event))) + rc= FAIL; + else + { + if (!rpl->filename) + { + diag("error: filename not set"); + rc= FAIL; + } + else + diag("filename: %.*s", (int)rpl->filename_length, rpl->filename); + } + + mariadb_free_rpl_event(event); + mariadb_rpl_close(rpl); + mysql_close(mysql); + return rc; +} + struct my_tests_st my_tests[] = { {"test_rpl_async", test_rpl_async, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_rpl_semisync", test_rpl_semisync, TEST_CONNECTION_NEW, 0, NULL, NULL}, + {"test_conc467", test_conc467, TEST_CONNECTION_NEW, 0, NULL, NULL}, {NULL, NULL, 0, 0, NULL, NULL} };