MXS-1383: abort slave connection if requested filename doesn't exist

MXS-1383: abort slave connection if requested filename doesn't exist
This commit is contained in:
MassimilianoPinto
2017-09-08 18:43:01 +02:00
parent 9617119aa9
commit 6606983181
4 changed files with 92 additions and 35 deletions

View File

@ -1038,6 +1038,8 @@ extern bool blr_fetch_mariadb_gtid(ROUTER_SLAVE *,
const char *,
MARIADB_GTID_INFO *);
extern void blr_start_master_in_main(void* data);
extern bool blr_binlog_file_exists(ROUTER_INSTANCE *router,
const char *log_name);
MXS_END_DECLS

View File

@ -4486,17 +4486,25 @@ bool blr_is_current_binlog(ROUTER_INSTANCE *router,
}
/**
* Check whether the current binlog file exists.
* Check whether a binlog file exists.
*
* The file could have been manually removed by mistake.
* The check is done when ROTATE event (real or fake) is seen by
* blr_rotate_event().
* The check is done when:
* ROTATE event (real or fake) is seen by blr_rotate_event()
* or
* when a slave connects with a binlog_file name.
*
* If param log_file is NULL, the current router->binlog_name
* is checked.
*
*
* @param router The router instance
* @param log_file The file name to check
* @return True if file exists, false otherwise.
*
*/
bool blr_file_exists(ROUTER_INSTANCE *router)
bool blr_binlog_file_exists(ROUTER_INSTANCE *router,
const char *log_file)
{
bool ret = true;
char path[PATH_MAX + 1] = "";
@ -4518,15 +4526,22 @@ bool blr_file_exists(ROUTER_INSTANCE *router)
}
// Set final file name full path
strcat(path, router->binlog_name);
strcat(path,
log_file == NULL ?
router->binlog_name :
log_file);
// Check file
if (access(path, F_OK) == -1 && errno == ENOENT)
{
// No file found
MXS_WARNING("%s: ROTATE_EVENT, missing binlog file %s ",
MXS_WARNING("%s: %s, missing binlog file '%s'",
router->service->name,
log_file == NULL ?
"ROTATE_EVENT" :
"Slave request",
path);
ret = false;
}

View File

@ -145,7 +145,6 @@ extern int blr_file_new_binlog(ROUTER_INSTANCE *router, char *file);
static bool blr_handle_missing_files(ROUTER_INSTANCE *router,
char *new_file);
static void worker_cb_start_master(int worker_id, void* data);
extern bool blr_file_exists(ROUTER_INSTANCE *router);
extern void blr_file_update_gtid(ROUTER_INSTANCE *router);
static int blr_check_connect_retry(ROUTER_INSTANCE *router);
@ -1633,9 +1632,9 @@ blr_rotate_event(ROUTER_INSTANCE *router, uint8_t *ptr, REP_HEADER *hdr)
int rotated = 1;
int remove_encrytion_ctx = 0;
/* Different file name in rotate event or missing binlog file */
/* Different file name in rotate event or missing current binlog file */
if ((strncmp(router->binlog_name, file, slen) != 0) ||
!blr_file_exists(router))
!blr_binlog_file_exists(router, NULL))
{
remove_encrytion_ctx = 1;
router->stats.n_rotates++;

View File

@ -363,6 +363,8 @@ static void blr_abort_change_master(ROUTER_INSTANCE *router,
MASTER_SERVER_CFG *current_master,
CHANGE_MASTER_OPTIONS *change_master,
const char *error);
static void blr_slave_abort_dump_request(ROUTER_SLAVE *slave,
const char *errmsg);
/**
* Process a request packet from the slave server.
*
@ -1847,30 +1849,22 @@ blr_slave_binlog_dump(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue
{
if (binlognamelen > BINLOG_FNAMELEN)
{
/* Abort the request */
char req_file[binlognamelen + 1];
char errmsg[BINLOG_ERROR_MSG_LEN + 1];
memcpy(req_file, (char *)ptr, binlognamelen);
req_file[binlognamelen] = 0;
MXS_ERROR("Slave %lu requests COM_BINLOG_DUMP with a filename %s"
" longer than max %d chars. Aborting.",
(unsigned long)slave->serverid,
snprintf(errmsg,
BINLOG_ERROR_MSG_LEN,
"Requested filename %s is longer than max %d chars.",
req_file,
BINLOG_FNAMELEN);
snprintf(errmsg, BINLOG_ERROR_MSG_LEN,
"Connecting slave requested binlog"
" file name %s longer than max %d chars.",
req_file,
BINLOG_FNAMELEN);
errmsg[BINLOG_ERROR_MSG_LEN] = '\0';
blr_send_custom_error(slave->dcb,
slave->seqno + 1,
0,
errmsg,
"HY000",
BINLOG_FATAL_ERROR_READING);
// ERROR
blr_slave_abort_dump_request(slave, errmsg);
slave->state = BLRS_ERRORED;
dcb_close(slave->dcb);
return 1;
@ -1893,6 +1887,7 @@ blr_slave_binlog_dump(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue
binlognamelen > 0,
requested_pos))
{
// ERROR
slave->state = BLRS_ERRORED;
dcb_close(slave->dcb);
return 1;
@ -1959,6 +1954,24 @@ blr_slave_binlog_dump(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue
strlen(slave->binlogfile),
(unsigned long)slave->binlog_pos);
/* Check first the requested file exists */
if (!blr_binlog_file_exists(router, slave->binlogfile))
{
char errmsg[BINLOG_ERROR_MSG_LEN + 1];
snprintf(errmsg, BINLOG_ERROR_MSG_LEN,
"Requested file name '%s' doesn't exist",
slave->binlogfile);
errmsg[BINLOG_ERROR_MSG_LEN] = '\0';
// ERROR
blr_slave_abort_dump_request(slave, errmsg);
slave->state = BLRS_ERRORED;
dcb_close(slave->dcb);
return 1;
}
/* First reply starts from seq = 1 */
slave->seqno = 1;
@ -6888,14 +6901,19 @@ static bool blr_slave_gtid_request(ROUTER_INSTANCE *router,
/* Requested GTID Not Found */
if (!f_gtid.gtid)
{
MXS_WARNING("Requested MariaDB GTID '%s' by server %lu"
char errmsg[BINLOG_ERROR_MSG_LEN + 1];
snprintf(errmsg,
BINLOG_ERROR_MSG_LEN,
"Requested MariaDB GTID '%s' by server %lu"
" has not been found",
slave->mariadb_gtid,
(unsigned long)slave->serverid);
errmsg[BINLOG_ERROR_MSG_LEN] = '\0';
/* Check strict mode */
if (slave->gtid_strict_mode)
{
MXS_ERROR("%s", errmsg);
strcpy(slave->binlogfile, "");
slave->binlog_pos = 0;
blr_send_custom_error(slave->dcb,
@ -6910,6 +6928,7 @@ static bool blr_slave_gtid_request(ROUTER_INSTANCE *router,
else
{
/* No strict mode: */
MXS_WARNING("%s", errmsg);
// - 1 -Set request GTID as current master one
MXS_FREE(slave->mariadb_gtid);
@ -6962,8 +6981,8 @@ static bool blr_slave_gtid_request(ROUTER_INSTANCE *router,
* The binlog file could be different due to:
* a rotate event or other non GTID events written
* after that GTID.
* If file exists events will be sent from requested file@pos
* otherwise file & pos = GTID info file.
* If file exists and pos >=4, events will be sent
* from requested file@pos, otherwise from GTID file & pos.
*/
// Add tree prefix
@ -6982,7 +7001,8 @@ static bool blr_slave_gtid_request(ROUTER_INSTANCE *router,
router->binlogdir,
file_path,
t_prefix[0] ? t_prefix: NULL);
if (blr_slave_get_file_size(file_path) != 0)
// File size is >=4 read: set pos.
if (blr_slave_get_file_size(file_path) >= 4)
{
slave->binlog_pos = req_pos;
}
@ -9131,3 +9151,24 @@ static void blr_abort_change_master(ROUTER_INSTANCE *router,
/* Free parsed options */
blr_master_free_parsed_options(change_master);
}
/**
* Abort the COM_BINLOG_DUMP slave request
*
* @param slave The connecting slave
* @param errmsg Error message to send and log
*/
static void blr_slave_abort_dump_request(ROUTER_SLAVE *slave,
const char *errmsg)
{
MXS_ERROR("Slave %lu requests COM_BINLOG_DUMP: %s. Aborting.",
(unsigned long)slave->serverid,
errmsg);
blr_send_custom_error(slave->dcb,
slave->seqno + 1,
0,
errmsg,
"HY000",
BINLOG_FATAL_ERROR_READING);
}