MXS-1545: fix file pointer reuse in blr_open_binlog
When binlog storage is TREE the check for existing BLFILE should use gtid info in addition to strcmp
This commit is contained in:
@ -200,7 +200,7 @@ static int gtid_file_select_cb(void *data,
|
|||||||
int cols,
|
int cols,
|
||||||
char** values,
|
char** values,
|
||||||
char** names);
|
char** names);
|
||||||
bool blr_compare_binlogs(ROUTER_INSTANCE *router,
|
bool blr_compare_binlogs(const ROUTER_INSTANCE *router,
|
||||||
const MARIADB_GTID_ELEMS *info,
|
const MARIADB_GTID_ELEMS *info,
|
||||||
const char *r_file,
|
const char *r_file,
|
||||||
const char *s_file);
|
const char *s_file);
|
||||||
@ -369,8 +369,8 @@ blr_file_init(ROUTER_INSTANCE *router)
|
|||||||
{
|
{
|
||||||
char f_prefix[BINLOG_FILE_EXTRA_INFO] = "";
|
char f_prefix[BINLOG_FILE_EXTRA_INFO] = "";
|
||||||
MARIADB_GTID_INFO last_gtid;
|
MARIADB_GTID_INFO last_gtid;
|
||||||
|
|
||||||
memset(&last_gtid, 0, sizeof(last_gtid));
|
memset(&last_gtid, 0, sizeof(last_gtid));
|
||||||
|
|
||||||
// SELECT LAST FILE
|
// SELECT LAST FILE
|
||||||
if (!blr_get_last_file(router, &last_gtid) ||
|
if (!blr_get_last_file(router, &last_gtid) ||
|
||||||
!last_gtid.gtid[0])
|
!last_gtid.gtid[0])
|
||||||
@ -802,6 +802,40 @@ blr_file_flush(ROUTER_INSTANCE *router)
|
|||||||
fsync(router->binlog_fd);
|
fsync(router->binlog_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the BLFILE file pointer has same informations
|
||||||
|
* as in MARIADB_GTID_INFO pointer
|
||||||
|
* and if binlog files are the same.
|
||||||
|
*
|
||||||
|
* This routine is used in blr_open_binlog()
|
||||||
|
* in order to use an already opened BLFILE file
|
||||||
|
* or open a new one.
|
||||||
|
*
|
||||||
|
* @param file Pointer to a BLFILE opened file
|
||||||
|
* @param binlog The slave binlog name
|
||||||
|
* @param info The MARIADB_GTID_INFO GTID info of
|
||||||
|
* current slave file
|
||||||
|
* @param s_tree Whether to use MARIADB_GTID_INFO info
|
||||||
|
* @return True if BLFILE can be reused, false otherwise
|
||||||
|
*/
|
||||||
|
static bool inline blr_is_same_slave_file(const BLFILE *file,
|
||||||
|
const char *binlog,
|
||||||
|
const MARIADB_GTID_INFO *info,
|
||||||
|
bool s_tree)
|
||||||
|
{
|
||||||
|
if (s_tree)
|
||||||
|
{
|
||||||
|
return (file->info.domain_id == info->gtid_elms.domain_id) &&
|
||||||
|
(file->info.server_id == info->gtid_elms.server_id) &&
|
||||||
|
(strcmp(file->binlogname, binlog) == 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return strcmp(file->binlogname, binlog) == 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a binlog file for reading binlog records
|
* Open a binlog file for reading binlog records
|
||||||
*
|
*
|
||||||
@ -847,13 +881,20 @@ blr_open_binlog(ROUTER_INSTANCE *router,
|
|||||||
|
|
||||||
spinlock_acquire(&router->fileslock);
|
spinlock_acquire(&router->fileslock);
|
||||||
file = router->files;
|
file = router->files;
|
||||||
while (file && strcmp(file->binlogname, binlog) != 0)
|
|
||||||
|
while (file &&
|
||||||
|
/* Check whether 'file' can be reused */
|
||||||
|
!blr_is_same_slave_file(file,
|
||||||
|
binlog,
|
||||||
|
info,
|
||||||
|
router->storage_type == BLR_BINLOG_STORAGE_TREE))
|
||||||
{
|
{
|
||||||
file = file->next;
|
file = file->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
{
|
{
|
||||||
|
/* Reuse 'file' */
|
||||||
file->refcnt++;
|
file->refcnt++;
|
||||||
spinlock_release(&router->fileslock);
|
spinlock_release(&router->fileslock);
|
||||||
return file;
|
return file;
|
||||||
@ -881,7 +922,7 @@ blr_open_binlog(ROUTER_INSTANCE *router,
|
|||||||
strcpy(path, router->binlogdir);
|
strcpy(path, router->binlogdir);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
|
|
||||||
// Add tree prefix: "domain_id/server_id"
|
/* Add tree prefix: "domain_id/server_id" */
|
||||||
if (info)
|
if (info)
|
||||||
{
|
{
|
||||||
char t_prefix[BINLOG_FILE_EXTRA_INFO];
|
char t_prefix[BINLOG_FILE_EXTRA_INFO];
|
||||||
@ -892,7 +933,7 @@ blr_open_binlog(ROUTER_INSTANCE *router,
|
|||||||
strcat(path, t_prefix);
|
strcat(path, t_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add file name
|
/* Add file name */
|
||||||
strcat(path, binlog);
|
strcat(path, binlog);
|
||||||
|
|
||||||
if ((file->fd = open(path, O_RDONLY, 0666)) == -1)
|
if ((file->fd = open(path, O_RDONLY, 0666)) == -1)
|
||||||
@ -1056,12 +1097,8 @@ blr_read_binlog(ROUTER_INSTANCE *router,
|
|||||||
switch (n)
|
switch (n)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
MXS_INFO("Reached end of binlog file '%s' at %lu.",
|
/* Just set ok indicator: nothing to log*/
|
||||||
file->binlogname, pos);
|
|
||||||
|
|
||||||
/* set ok indicator */
|
|
||||||
hdr->ok = SLAVE_POS_READ_OK;
|
hdr->ok = SLAVE_POS_READ_OK;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
{
|
{
|
||||||
@ -1569,6 +1606,15 @@ blr_cache_read_response(ROUTER_INSTANCE *router, char *response)
|
|||||||
/**
|
/**
|
||||||
* Does the next binlog file in the sequence for the slave exist.
|
* Does the next binlog file in the sequence for the slave exist.
|
||||||
*
|
*
|
||||||
|
* If the next file exists in the GTID maps_repo,
|
||||||
|
* no matter if it's not readable in the filesystem,
|
||||||
|
* the GTID elems in the slave->f_info struct will be overwritten.
|
||||||
|
* - file
|
||||||
|
* - domain_id
|
||||||
|
* - server_id
|
||||||
|
*
|
||||||
|
* Note: slave->binlogfile is always untouched
|
||||||
|
*
|
||||||
* @param router The router instance
|
* @param router The router instance
|
||||||
* @param slave The slave in question
|
* @param slave The slave in question
|
||||||
* @param next_file The next_file buffer
|
* @param next_file The next_file buffer
|
||||||
@ -1654,11 +1700,8 @@ blr_file_next_exists(ROUTER_INSTANCE *router,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MXS_INFO("The next Binlog file from GTID maps repo is %s",
|
|
||||||
result.file);
|
|
||||||
|
|
||||||
// Check whether the query has a result
|
// Check whether the query has a result
|
||||||
if (result.file)
|
if (result.file[0])
|
||||||
{
|
{
|
||||||
// Full filename path
|
// Full filename path
|
||||||
sprintf(bigbuf,
|
sprintf(bigbuf,
|
||||||
@ -1671,17 +1714,32 @@ blr_file_next_exists(ROUTER_INSTANCE *router,
|
|||||||
strncpy(next_file, result.file, BINLOG_FNAMELEN);
|
strncpy(next_file, result.file, BINLOG_FNAMELEN);
|
||||||
next_file[BINLOG_FNAMELEN] = '\0';
|
next_file[BINLOG_FNAMELEN] = '\0';
|
||||||
|
|
||||||
|
MXS_INFO("The next Binlog file from GTID maps repo is [%s]",
|
||||||
|
bigbuf);
|
||||||
|
|
||||||
|
spinlock_acquire(&slave->catch_lock);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update GTID elems in the slave->f_info struct:
|
* Update GTID elems in the slave->f_info struct:
|
||||||
* file and domain_id / server_id
|
* file and domain_id / server_id
|
||||||
|
* Note: slave->binlogfile is untouched
|
||||||
*/
|
*/
|
||||||
|
|
||||||
strcpy(slave->f_info.file, result.file);
|
strcpy(slave->f_info.file, result.file);
|
||||||
slave->f_info.gtid_elms.domain_id = result.gtid_elms.domain_id;
|
slave->f_info.gtid_elms.domain_id = result.gtid_elms.domain_id;
|
||||||
slave->f_info.gtid_elms.server_id = result.gtid_elms.server_id;
|
slave->f_info.gtid_elms.server_id = result.gtid_elms.server_id;
|
||||||
|
|
||||||
|
spinlock_release(&slave->catch_lock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MXS_WARNING("The next Binlog file from GTID maps repo "
|
||||||
|
"of current slave file [%" PRIu32 "/%" PRIu32 "/%s] "
|
||||||
|
"has not been found. Router state is [%s]",
|
||||||
|
slave->f_info.gtid_elms.domain_id,
|
||||||
|
slave->f_info.gtid_elms.server_id,
|
||||||
|
slave->binlogfile,
|
||||||
|
blrm_states[router->master_state]);
|
||||||
|
|
||||||
next_file[0] = '\0';
|
next_file[0] = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1690,6 +1748,9 @@ blr_file_next_exists(ROUTER_INSTANCE *router,
|
|||||||
// Check whether the new file exists
|
// Check whether the new file exists
|
||||||
if (access(bigbuf, R_OK) == -1)
|
if (access(bigbuf, R_OK) == -1)
|
||||||
{
|
{
|
||||||
|
MXS_ERROR("The next Binlog file [%s] from GTID maps repo "
|
||||||
|
"cannot be read or accessed.",
|
||||||
|
bigbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -2641,9 +2702,6 @@ blr_read_events_all_events(ROUTER_INSTANCE *router,
|
|||||||
f_prefix,
|
f_prefix,
|
||||||
gtid_info.file);
|
gtid_info.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
MXS_FREE(gtid_info.gtid);
|
|
||||||
MXS_FREE(gtid_info.file);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4413,7 +4471,7 @@ bool blr_get_last_file(ROUTER_INSTANCE *router,
|
|||||||
* @param s_file The slave file
|
* @param s_file The slave file
|
||||||
* @return True or false
|
* @return True or false
|
||||||
*/
|
*/
|
||||||
bool blr_compare_binlogs(ROUTER_INSTANCE *router,
|
bool blr_compare_binlogs(const ROUTER_INSTANCE *router,
|
||||||
const MARIADB_GTID_ELEMS *info,
|
const MARIADB_GTID_ELEMS *info,
|
||||||
const char *r_file,
|
const char *r_file,
|
||||||
const char *s_file)
|
const char *s_file)
|
||||||
@ -4462,9 +4520,9 @@ bool blr_is_current_binlog(ROUTER_INSTANCE *router,
|
|||||||
* is checked.
|
* is checked.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @param router The router instance
|
* @param router The router instance
|
||||||
* @param log_file The file name to check
|
* @param info_file The GTID info file name to check
|
||||||
* @return True if file exists, false otherwise.
|
* @return True if file exists, false otherwise.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
bool blr_binlog_file_exists(ROUTER_INSTANCE *router,
|
bool blr_binlog_file_exists(ROUTER_INSTANCE *router,
|
||||||
|
@ -340,8 +340,8 @@ static bool blr_handle_complex_select(ROUTER_INSTANCE *router,
|
|||||||
const char *coln);
|
const char *coln);
|
||||||
extern bool blr_is_current_binlog(ROUTER_INSTANCE *router,
|
extern bool blr_is_current_binlog(ROUTER_INSTANCE *router,
|
||||||
ROUTER_SLAVE *slave);
|
ROUTER_SLAVE *slave);
|
||||||
extern bool blr_compare_binlogs(ROUTER_INSTANCE *router,
|
extern bool blr_compare_binlogs(const ROUTER_INSTANCE *router,
|
||||||
MARIADB_GTID_INFO *slave,
|
const MARIADB_GTID_INFO *slave,
|
||||||
const char *r_file,
|
const char *r_file,
|
||||||
const char *s_file);
|
const char *s_file);
|
||||||
static bool blr_purge_binary_logs(ROUTER_INSTANCE *router,
|
static bool blr_purge_binary_logs(ROUTER_INSTANCE *router,
|
||||||
|
Reference in New Issue
Block a user