MXS-1266: Master GTID registration: MASTER_USE_GTID=Slave_pos
MASTER_USE_GTID=Slave_pos is now handled by CHANGE MASTER TO If mariadb10_master_gtid is On MASTER_LOG_FILE is no longer required, only MASTER_USE_GTID=Slave_pos Slave_pos must be set before to empty value or request value: set @@global.gtid_slave_pos = '0-10116-194';
This commit is contained in:
@ -687,18 +687,21 @@ createInstance(SERVICE *service, char **options)
|
||||
else
|
||||
{
|
||||
MXS_ERROR("%s: Error: No router options supplied for binlogrouter",
|
||||
service->name);
|
||||
service->name);
|
||||
}
|
||||
|
||||
inst->orig_masterid = 0;
|
||||
inst->mariadb10_gtid_domain = BLR_DEFAULT_GTID_DOMAIN_ID;
|
||||
|
||||
/* Override master_id */
|
||||
if (inst->masterid)
|
||||
{
|
||||
inst->set_master_server_id = true;
|
||||
}
|
||||
|
||||
if ((inst->binlogdir == NULL) ||
|
||||
(inst->binlogdir != NULL && !strlen(inst->binlogdir)))
|
||||
(inst->binlogdir != NULL &&
|
||||
!strlen(inst->binlogdir)))
|
||||
{
|
||||
MXS_ERROR("Service %s, binlog directory is not specified",
|
||||
service->name);
|
||||
@ -956,7 +959,9 @@ createInstance(SERVICE *service, char **options)
|
||||
/* Read any cached response messages */
|
||||
blr_cache_read_master_data(inst);
|
||||
|
||||
/* Find latest binlog file */
|
||||
/**
|
||||
* Find latest binlog file in binlogdir or GTID maps repo
|
||||
*/
|
||||
if (blr_file_init(inst) == 0)
|
||||
{
|
||||
MXS_ERROR("%s: Service not started due to lack of binlog directory %s",
|
||||
@ -1036,6 +1041,7 @@ createInstance(SERVICE *service, char **options)
|
||||
f_prefix,
|
||||
inst->binlog_name);
|
||||
|
||||
/* Check current binlog */
|
||||
if (!blr_check_binlog(inst))
|
||||
{
|
||||
if (inst->trx_safe || inst->encryption.enabled)
|
||||
@ -1047,8 +1053,8 @@ createInstance(SERVICE *service, char **options)
|
||||
}
|
||||
}
|
||||
|
||||
/* Report current pos in binlog file and last seen transaction pos */
|
||||
MXS_INFO("Current binlog file is %s, safe pos %lu, current pos is %lu\n",
|
||||
/* Log current pos in binlog file and last seen transaction pos */
|
||||
MXS_INFO("Current binlog file is %s, safe pos %lu, current pos is %lu",
|
||||
inst->binlog_name, inst->binlog_position, inst->current_pos);
|
||||
|
||||
/**
|
||||
@ -1102,7 +1108,10 @@ createInstance(SERVICE *service, char **options)
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't start replication if binlog has START_ENCRYPTION_EVENT but binlog encryption is off */
|
||||
/**
|
||||
* Don't start replication if binlog has START_ENCRYPTION_EVENT
|
||||
* but binlog encryption is off
|
||||
*/
|
||||
if (!inst->encryption.enabled && inst->encryption_ctx)
|
||||
{
|
||||
MXS_ERROR("Found START_ENCRYPTION_EVENT but "
|
||||
@ -1211,7 +1220,6 @@ newSession(MXS_ROUTER *instance, MXS_SESSION *session)
|
||||
slave->lastEventReceived = 0;
|
||||
slave->encryption_ctx = NULL;
|
||||
slave->mariadb_gtid = NULL;
|
||||
|
||||
slave->gtid_maps = NULL;
|
||||
memset(&slave->f_info, 0 , sizeof (MARIADB_GTID_INFO));
|
||||
|
||||
@ -2573,7 +2581,7 @@ int
|
||||
blr_send_custom_error(DCB *dcb,
|
||||
int packet_number,
|
||||
int affected_rows,
|
||||
char *msg,
|
||||
const char *msg,
|
||||
char *statemsg,
|
||||
unsigned int errcode)
|
||||
{
|
||||
|
@ -105,6 +105,9 @@ MXS_BEGIN_DECLS
|
||||
*/
|
||||
#define BINLOG_FILE_EXTRA_INFO GTID_MAX_LEN
|
||||
|
||||
/* Default MariaDB GTID Domain Id */
|
||||
#define BLR_DEFAULT_GTID_DOMAIN_ID 0
|
||||
|
||||
enum binlog_storage_type
|
||||
{
|
||||
BLR_BINLOG_STORAGE_FLAT,
|
||||
@ -362,6 +365,8 @@ typedef struct master_server_config
|
||||
char *ssl_ca;
|
||||
int ssl_enabled;
|
||||
char *ssl_version;
|
||||
/* MariaDB 10 GTID */
|
||||
char *use_mariadb10_gtid;
|
||||
} MASTER_SERVER_CFG;
|
||||
|
||||
/* Config struct for CHANGE MASTER TO options */
|
||||
@ -379,6 +384,8 @@ typedef struct change_master_options
|
||||
char *ssl_ca;
|
||||
char *ssl_enabled;
|
||||
char *ssl_version;
|
||||
/* MariaDB 10 GTID */
|
||||
char *use_mariadb10_gtid;
|
||||
} CHANGE_MASTER_OPTIONS;
|
||||
|
||||
/**
|
||||
@ -979,7 +986,7 @@ extern int blr_ping(ROUTER_INSTANCE *, ROUTER_SLAVE *, GWBUF *);
|
||||
extern int blr_send_custom_error(DCB *,
|
||||
int,
|
||||
int,
|
||||
char *,
|
||||
const char *,
|
||||
char *,
|
||||
unsigned int);
|
||||
extern int blr_file_next_exists(ROUTER_INSTANCE *,
|
||||
|
@ -450,13 +450,20 @@ blr_file_init(ROUTER_INSTANCE *router)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate the current log file with new one
|
||||
*
|
||||
* @param router The router instance
|
||||
* @param file The new file to create
|
||||
* @param pos The binlog position (not used)
|
||||
* @return 1 on succes, 0 on failure
|
||||
*/
|
||||
int
|
||||
blr_file_rotate(ROUTER_INSTANCE *router, char *file, uint64_t pos)
|
||||
{
|
||||
return blr_file_create(router, file);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* binlog files need an initial 4 magic bytes at the start. blr_file_add_magic()
|
||||
* adds them.
|
||||
@ -474,7 +481,6 @@ blr_file_add_magic(int fd)
|
||||
return written == BINLOG_MAGIC_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new binlog file for the router to use.
|
||||
*
|
||||
@ -511,11 +517,15 @@ blr_file_create(ROUTER_INSTANCE *router, char *file)
|
||||
{
|
||||
char prefix[BINLOG_FILE_EXTRA_INFO];
|
||||
sprintf(prefix,
|
||||
"%" PRIu32 "/%" PRIu32 "/",
|
||||
router->mariadb10_gtid_domain,
|
||||
router->orig_masterid);
|
||||
"%" PRIu32 "/",
|
||||
router->mariadb10_gtid_domain);
|
||||
|
||||
// Add domain_id
|
||||
strcat(path, prefix);
|
||||
|
||||
/**
|
||||
* - 1 - Check and create $domain_id dir
|
||||
*/
|
||||
if (access(path, R_OK) == -1)
|
||||
{
|
||||
int mkdir_rval;
|
||||
@ -523,7 +533,32 @@ blr_file_create(ROUTER_INSTANCE *router, char *file)
|
||||
if (mkdir_rval == -1)
|
||||
{
|
||||
MXS_ERROR("Service %s, Failed to create binlog"
|
||||
" directory tree '%s': [%d] %s",
|
||||
" directory tree (domain_id) '%s': [%d] %s",
|
||||
router->service->name,
|
||||
path,
|
||||
errno,
|
||||
mxs_strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Add server_id
|
||||
sprintf(prefix,
|
||||
"%" PRIu32 "/",
|
||||
router->orig_masterid);
|
||||
strcat(path, prefix);
|
||||
|
||||
/**
|
||||
* - 2 - Check and create $server_id dir under $domain_id
|
||||
*/
|
||||
if (access(path, R_OK) == -1)
|
||||
{
|
||||
int mkdir_rval;
|
||||
mkdir_rval = mkdir(path, 0700);
|
||||
if (mkdir_rval == -1)
|
||||
{
|
||||
MXS_ERROR("Service %s, Failed to create binlog"
|
||||
" directory tree (domain_id/server_id) '%s': [%d] %s",
|
||||
router->service->name,
|
||||
path,
|
||||
errno,
|
||||
@ -1289,7 +1324,7 @@ blr_read_binlog(ROUTER_INSTANCE *router,
|
||||
{
|
||||
snprintf(errmsg,
|
||||
BINLOG_ERROR_MSG_LEN,
|
||||
"Error reading the binlog event at %lu in binlog file '%s';"
|
||||
"Error reading the binlog event at %lu in binlog file '%s'; "
|
||||
"(%s), expected %d bytes.",
|
||||
pos,
|
||||
file->binlogname,
|
||||
@ -3257,7 +3292,7 @@ blr_create_ignorable_event(uint32_t event_size,
|
||||
{
|
||||
MXS_ERROR("blr_create_ignorable_event an event of %lu bytes"
|
||||
" is not valid in blr_file.c",
|
||||
(unsigned long)event_size);
|
||||
(unsigned long)event_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -4113,14 +4148,17 @@ static int gtid_select_cb(void *data,
|
||||
result->file = MXS_STRDUP_A(values[1]);
|
||||
result->start = atoll(values[2]);
|
||||
result->end = atoll(values[3]);
|
||||
if (cols > 4)
|
||||
|
||||
if (cols > 4 &&
|
||||
(values[4] &&
|
||||
values[5] &&
|
||||
values[6]))
|
||||
{
|
||||
result->gtid_elms.domain_id = atoll(values[4]);
|
||||
result->gtid_elms.server_id = atoll(values[5]);
|
||||
result->gtid_elms.seq_no = atoll(values[6]);
|
||||
}
|
||||
|
||||
ss_dassert(result->start > 0 && result->start > 0);
|
||||
if (result->start > 4)
|
||||
{
|
||||
ss_dassert(result->end > result->start);
|
||||
@ -4149,6 +4187,14 @@ bool blr_fetch_mariadb_gtid(ROUTER_SLAVE *slave,
|
||||
char *errmsg = NULL;
|
||||
char select_query[GTID_SQL_BUFFER_SIZE];
|
||||
MARIADB_GTID_ELEMS gtid_elms = {};
|
||||
/* The fields in the WHERE clause belong to
|
||||
* primary key but binlog_file cannot be part of
|
||||
* WHERE because GTID is made of X-Y-Z, three elements.
|
||||
*
|
||||
* The query has ORDER BY id DESC LIMIT 1 in order
|
||||
* to get the right GTID, even in case of database
|
||||
* with old content.
|
||||
*/
|
||||
static const char select_tpl[] = "SELECT "
|
||||
"(rep_domain ||"
|
||||
" '-' || server_id ||"
|
||||
@ -4162,7 +4208,8 @@ bool blr_fetch_mariadb_gtid(ROUTER_SLAVE *slave,
|
||||
"FROM gtid_maps "
|
||||
"WHERE (rep_domain = %" PRIu32 " AND "
|
||||
"server_id = %" PRIu32 " AND "
|
||||
"sequence = %" PRIu64 ");";
|
||||
"sequence = %" PRIu64 ") "
|
||||
"ORDER BY id DESC LIMIT 1;";
|
||||
ss_dassert(gtid != NULL);
|
||||
|
||||
/* Parse GTID value into its components */
|
||||
@ -4448,7 +4495,7 @@ bool blr_compare_binlogs(ROUTER_INSTANCE *router,
|
||||
// domain_id, server_id and strcmp()
|
||||
return ((router->mariadb10_gtid_domain == info->domain_id) &&
|
||||
(router->orig_masterid == info->server_id) &&
|
||||
strcmp(r_file, r_file) == 0);
|
||||
strcmp(r_file, s_file) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3107,6 +3107,13 @@ static void blr_register_mariadb_gtid_request(ROUTER_INSTANCE *router,
|
||||
/**
|
||||
* The routine hanldes a Fake ROTATE_EVENT
|
||||
*
|
||||
* It takes care of any missing file between
|
||||
* current file and the one in rotate event:
|
||||
* files with 4 bytes size colud be created.
|
||||
*
|
||||
* The filename specified in rotate event
|
||||
* is created/overwritten
|
||||
*
|
||||
* @param router The router instance
|
||||
* @param hdr The Replication event header
|
||||
* @param ptr The packet data
|
||||
@ -3240,7 +3247,7 @@ static void blr_handle_fake_gtid_list(ROUTER_INSTANCE *router,
|
||||
}
|
||||
else
|
||||
{
|
||||
// Increment internal offsets
|
||||
// Increment the internal offsets
|
||||
spinlock_acquire(&router->binlog_lock);
|
||||
|
||||
router->last_written = hdr->next_pos;
|
||||
@ -3275,12 +3282,14 @@ static bool blr_handle_missing_files(ROUTER_INSTANCE *router,
|
||||
char buf[BLRM_BINLOG_NAME_STR_LEN];
|
||||
char bigbuf[PATH_MAX + 1];
|
||||
|
||||
if ((fptr = strrchr(new_file, '.')) == NULL)
|
||||
if (*new_file &&
|
||||
(fptr = strrchr(new_file, '.')) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
new_fseqno = atol(fptr + 1);
|
||||
if ((fptr = strrchr(router->binlog_name, '.')) == NULL)
|
||||
if (*router->binlog_name &&
|
||||
(fptr = strrchr(router->binlog_name, '.')) == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -3288,7 +3297,10 @@ static bool blr_handle_missing_files(ROUTER_INSTANCE *router,
|
||||
int32_t delta_seq = new_fseqno - (curr_fseqno + 1);
|
||||
|
||||
/**
|
||||
* Try creating delta_seq empty binlog files
|
||||
* Try creating delta_seq empty binlog files:
|
||||
*
|
||||
* Note: currenlty working for positive delta
|
||||
* and same filestem.
|
||||
*/
|
||||
if (delta_seq > 0)
|
||||
{
|
||||
|
@ -398,7 +398,7 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
else if (router->mariadb10_compat && !slave->mariadb10_compat)
|
||||
{
|
||||
char *err_msg = "MariaDB 10 Slave is required"
|
||||
" for Slave registration.";
|
||||
" for Slave registration.";
|
||||
/**
|
||||
* If Master is MariaDB10 don't allow registration from
|
||||
* MariaDB/Mysql 5 Slaves
|
||||
@ -426,8 +426,8 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
* If GTID master replication is set
|
||||
* only GTID slaves can continue the registration.
|
||||
*/
|
||||
char *err_msg = "MariaDB 10 Slave GTID is required"
|
||||
" for Slave registration.";
|
||||
const char *err_msg = "MariaDB 10 Slave GTID is required"
|
||||
" for Slave registration.";
|
||||
slave->state = BLRS_ERRORED;
|
||||
/* Send error that stops slave replication */
|
||||
blr_send_custom_error(slave->dcb,
|
||||
@ -1091,7 +1091,7 @@ blr_slave_send_master_status(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave)
|
||||
}
|
||||
|
||||
/*
|
||||
* Columns to send for a "SHOW SLAVE STATUS" command
|
||||
* Columns to send for GTID in "SHOW SLAVE STATUS" command
|
||||
*/
|
||||
static const char *slave_status_columns[] =
|
||||
{
|
||||
@ -1150,7 +1150,7 @@ static const char *slave_status_columns[] =
|
||||
};
|
||||
|
||||
/*
|
||||
* New columns to send for a "SHOW ALL SLAVES STATUS" command
|
||||
* New columns to send for GTID in "SHOW ALL SLAVES STATUS" command
|
||||
*/
|
||||
static const char *all_slaves_status_columns[] =
|
||||
{
|
||||
@ -1220,6 +1220,7 @@ blr_slave_send_slave_status(ROUTER_INSTANCE *router,
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the right GTID columns array */
|
||||
const char **gtid_status_columns = router->mariadb10_gtid ?
|
||||
mariadb10_gtid_status_columns :
|
||||
mysql_gtid_status_columns;
|
||||
@ -1246,6 +1247,7 @@ blr_slave_send_slave_status(ROUTER_INSTANCE *router,
|
||||
seqno++);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now send column definitions for slave status */
|
||||
for (i = 0; slave_status_columns[i]; i++)
|
||||
{
|
||||
@ -2364,6 +2366,7 @@ blr_slave_catchup(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, bool large)
|
||||
if (hdr.event_type == ROTATE_EVENT)
|
||||
{
|
||||
unsigned long beat1 = hkheartbeat;
|
||||
|
||||
blr_close_binlog(router, file);
|
||||
if (hkheartbeat - beat1 > 1)
|
||||
{
|
||||
@ -2377,6 +2380,7 @@ blr_slave_catchup(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, bool large)
|
||||
slave->encryption_ctx = NULL;
|
||||
|
||||
beat1 = hkheartbeat;
|
||||
|
||||
#ifdef BLFILE_IN_SLAVE
|
||||
if ((slave->file = blr_open_binlog(router,
|
||||
slave->binlogfile,
|
||||
@ -2867,7 +2871,7 @@ blr_slave_read_fde(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* FDE is not encrypted, so we can pass NULL to last parameter */
|
||||
/* FDE, at pos 4, is not encrypted, pass NULL to last parameter */
|
||||
if ((record = blr_read_binlog(router,
|
||||
file,
|
||||
4,
|
||||
@ -3554,9 +3558,17 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
||||
router->master_state = BLRM_UNCONNECTED;
|
||||
spinlock_release(&router->lock);
|
||||
|
||||
/* create a new binlog or just use current one */
|
||||
/**
|
||||
* Check whether to create the new binlog (router->binlog_name)
|
||||
*
|
||||
* File handling happens only if mariadb10_master_gtid is off:
|
||||
* with Master GTID the first file will be created/opened
|
||||
* by the fake Rotate Event.
|
||||
*/
|
||||
|
||||
/* Check first for incomplete transaction */
|
||||
if (strlen(router->prevbinlog) &&
|
||||
strcmp(router->prevbinlog, router->binlog_name))
|
||||
strcmp(router->prevbinlog, router->binlog_name) != 0)
|
||||
{
|
||||
if (router->trx_safe &&
|
||||
router->pending_transaction.state > BLRM_NO_TRANSACTION)
|
||||
@ -3565,9 +3577,21 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
||||
char file[PATH_MAX + 1] = "";
|
||||
struct stat statb;
|
||||
unsigned long filelen = 0;
|
||||
char t_prefix[BINLOG_FILE_EXTRA_INFO] = "";
|
||||
|
||||
snprintf(file, PATH_MAX, "%s/%s",
|
||||
// Add file prefix
|
||||
if (router->storage_type == BLR_BINLOG_STORAGE_TREE)
|
||||
{
|
||||
sprintf(t_prefix,
|
||||
"%" PRIu32 "/%" PRIu32 "/",
|
||||
router->mariadb10_gtid_domain,
|
||||
router->orig_masterid);
|
||||
}
|
||||
|
||||
// Router current file
|
||||
snprintf(file, PATH_MAX, "%s/%s%s",
|
||||
router->binlogdir,
|
||||
t_prefix,
|
||||
router->prevbinlog);
|
||||
|
||||
/* Get file size */
|
||||
@ -3578,9 +3602,10 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
||||
|
||||
/* Prepare warning message */
|
||||
snprintf(msg, BINLOG_ERROR_MSG_LEN,
|
||||
"1105:Truncated partial transaction in file %s, "
|
||||
"1105:Truncated partial transaction in file %s%s, "
|
||||
"starting at pos %lu, "
|
||||
"ending at pos %lu. File %s now has length %lu.",
|
||||
t_prefix,
|
||||
router->prevbinlog,
|
||||
router->last_safe_pos,
|
||||
filelen,
|
||||
@ -3596,10 +3621,11 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
||||
|
||||
/* Log it */
|
||||
MXS_WARNING("A transaction is still opened at pos %lu"
|
||||
" File %s will be truncated. "
|
||||
" File %s%s will be truncated. "
|
||||
"Next binlog file is %s at pos %d, "
|
||||
"START SLAVE is required again.",
|
||||
router->last_safe_pos,
|
||||
t_prefix,
|
||||
router->prevbinlog,
|
||||
router->binlog_name,
|
||||
4);
|
||||
@ -3617,21 +3643,34 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
||||
|
||||
/* Send warning message to mysql command */
|
||||
blr_slave_send_warning_message(router, slave, msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* No file has beem opened, create a new binlog file */
|
||||
if (router->binlog_fd == -1)
|
||||
{
|
||||
blr_file_new_binlog(router, router->binlog_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A new binlog file has been created by CHANGE MASTER TO
|
||||
* if no pending transaction is detected.
|
||||
* use the existing one.
|
||||
*/
|
||||
blr_file_append(router, router->binlog_name);
|
||||
return 1;
|
||||
}
|
||||
/* No pending transaction */
|
||||
else
|
||||
{
|
||||
/**
|
||||
* If router->mariadb10_master_gtid is Off then
|
||||
* handle file create/append.
|
||||
* This means the domain_id and server_id
|
||||
* are not taken into account for filename prefix.
|
||||
*/
|
||||
if (!router->mariadb10_master_gtid)
|
||||
{
|
||||
/* If the router file is not open, create a new binlog file */
|
||||
if (router->binlog_fd == -1)
|
||||
{
|
||||
blr_file_new_binlog(router, router->binlog_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A new binlog file has been created and opened
|
||||
* by CHANGE MASTER TO: use it
|
||||
*/
|
||||
blr_file_append(router, router->binlog_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialise SSL: exit on error */
|
||||
@ -3644,7 +3683,8 @@ blr_start_slave(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave)
|
||||
|
||||
blr_slave_send_error_packet(slave,
|
||||
"Unable to initialise SSL with backend server",
|
||||
(unsigned int)1210, "HY000");
|
||||
1210,
|
||||
"HY000");
|
||||
spinlock_acquire(&router->lock);
|
||||
|
||||
router->master_state = BLRM_SLAVE_STOPPED;
|
||||
@ -3894,36 +3934,62 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
/**
|
||||
* If MASTER_LOG_FILE is not set
|
||||
* and master connection is configured
|
||||
* set master_logfile to current binlog_name
|
||||
* Otherwise return an error.
|
||||
* set master_logfile to current binlog_name.
|
||||
*
|
||||
* 'router->use_mariadb10_gtid' value is checked before
|
||||
* returning an error
|
||||
*/
|
||||
if (master_logfile == NULL)
|
||||
{
|
||||
int change_binlog_error = 0;
|
||||
bool change_binlog_error = true;
|
||||
const char *err_prefix = "Router is not configured "
|
||||
"for master connection,";
|
||||
/* Replication is not configured yet */
|
||||
if (router->master_state == BLRM_UNCONFIGURED)
|
||||
{
|
||||
/* if there is another error message keep it */
|
||||
if (!strlen(error))
|
||||
/* Check MASTER_USE_GTID option */
|
||||
if (router->mariadb10_master_gtid &&
|
||||
!change_master.use_mariadb10_gtid)
|
||||
{
|
||||
snprintf(error,
|
||||
BINLOG_ERROR_MSG_LEN,
|
||||
"Router is not configured for master connection, "
|
||||
"MASTER_LOG_FILE is required");
|
||||
"%s MASTER_USE_GTID=Slave_pos is required",
|
||||
err_prefix);
|
||||
}
|
||||
change_binlog_error = 1;
|
||||
else
|
||||
{
|
||||
/* If there is another error message keep it */
|
||||
if (!strlen(error) &&
|
||||
!change_master.use_mariadb10_gtid)
|
||||
{
|
||||
snprintf(error,
|
||||
BINLOG_ERROR_MSG_LEN,
|
||||
"%s MASTER_LOG_FILE is required",
|
||||
err_prefix);
|
||||
}
|
||||
}
|
||||
|
||||
change_binlog_error = strlen(error) ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if errors returned set error */
|
||||
if (strlen(error))
|
||||
/* If errors returned set error */
|
||||
if (strlen(error) &&
|
||||
(router->mariadb10_master_gtid &&
|
||||
!change_master.use_mariadb10_gtid))
|
||||
{
|
||||
change_binlog_error = 1;
|
||||
/* MASTER_USE_GTID option not set */
|
||||
snprintf(error,
|
||||
BINLOG_ERROR_MSG_LEN,
|
||||
"%s MASTER_USE_GTID=Slave_pos is required",
|
||||
err_prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use current binlog file */
|
||||
master_logfile = MXS_STRDUP_A(router->binlog_name);
|
||||
|
||||
change_binlog_error = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3941,13 +4007,44 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* master_log_file is not NULL */
|
||||
{
|
||||
/* Check for MASTER_USE_GTID option */
|
||||
const char *err_prefix = "Router is not configured "
|
||||
"for master connection,";
|
||||
if (router->mariadb10_master_gtid &&
|
||||
!change_master.use_mariadb10_gtid)
|
||||
{
|
||||
snprintf(error,
|
||||
BINLOG_ERROR_MSG_LEN,
|
||||
"%s MASTER_USE_GTID=Slave_pos is required",
|
||||
err_prefix);
|
||||
MXS_ERROR("%s: %s", router->service->name, error);
|
||||
|
||||
/* restore previous master_host and master_port */
|
||||
blr_master_restore_config(router, current_master);
|
||||
|
||||
blr_master_free_parsed_options(&change_master);
|
||||
|
||||
spinlock_release(&router->lock);
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If master connection is configured check new binlog name:
|
||||
* If binlog name has changed to next one only position 4 is allowed
|
||||
* If binlog name has changed to next one
|
||||
* then only position 4 is allowed
|
||||
*/
|
||||
|
||||
if (strcmp(master_logfile, router->binlog_name) &&
|
||||
/**
|
||||
* Check whether MASTER_USE_GTID option was set
|
||||
*/
|
||||
if ((router->mariadb10_master_gtid &&
|
||||
!change_master.use_mariadb10_gtid) &&
|
||||
strcmp(master_logfile, router->binlog_name) != 0 &&
|
||||
router->master_state != BLRM_UNCONFIGURED)
|
||||
{
|
||||
int return_error = 0;
|
||||
@ -4002,7 +4099,6 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
spinlock_release(&router->lock);
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4026,6 +4122,22 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
router->binlog_name);
|
||||
}
|
||||
}
|
||||
/* MariaDB 10 GTID request */
|
||||
else if (router->mariadb10_master_gtid &&
|
||||
change_master.use_mariadb10_gtid)
|
||||
{
|
||||
/* Set empty filename at pos 4 */
|
||||
strcpy(router->binlog_name, "");
|
||||
|
||||
router->current_pos = 4;
|
||||
router->binlog_position = 4;
|
||||
router->current_safe_event = 4;
|
||||
|
||||
MXS_INFO("%s: MASTER_USE_GTID is [%s], value [%s]",
|
||||
router->service->name,
|
||||
change_master.use_mariadb10_gtid,
|
||||
router->last_mariadb_gtid);
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
@ -4087,7 +4199,7 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
{
|
||||
/**
|
||||
* no pos change, set it to 4 if BLRM_UNCONFIGURED
|
||||
* Also set binlog name if UNCOFIGURED
|
||||
* Also set binlog name if UNCONFIGURED
|
||||
*/
|
||||
if (router->master_state == BLRM_UNCONFIGURED)
|
||||
{
|
||||
@ -4108,11 +4220,10 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
}
|
||||
|
||||
/* Log config changes (without passwords) */
|
||||
|
||||
MXS_NOTICE("%s: 'CHANGE MASTER TO executed'. Previous state "
|
||||
"MASTER_HOST='%s', MASTER_PORT=%i, MASTER_LOG_FILE='%s', "
|
||||
"MASTER_LOG_POS=%lu, MASTER_USER='%s'. New state is MASTER_HOST='%s', "
|
||||
"MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'",
|
||||
"MASTER_PORT=%i, MASTER_LOG_FILE='%s', MASTER_LOG_POS=%lu, MASTER_USER='%s'%s",
|
||||
router->service->name,
|
||||
current_master->host,
|
||||
current_master->port,
|
||||
@ -4123,7 +4234,10 @@ int blr_handle_change_master(ROUTER_INSTANCE* router,
|
||||
router->service->dbref->server->port,
|
||||
router->binlog_name,
|
||||
router->current_pos,
|
||||
router->user);
|
||||
router->user,
|
||||
change_master.use_mariadb10_gtid ?
|
||||
", MASTER_USE_GTID=Slave_pos" :
|
||||
"");
|
||||
|
||||
blr_master_free_config(current_master);
|
||||
|
||||
@ -4412,6 +4526,8 @@ blr_master_free_config(MASTER_SERVER_CFG *master_cfg)
|
||||
MXS_FREE(master_cfg->ssl_cert);
|
||||
MXS_FREE(master_cfg->ssl_ca);
|
||||
MXS_FREE(master_cfg->ssl_version);
|
||||
/* MariaDB 10 GTID */
|
||||
MXS_FREE(master_cfg->use_mariadb10_gtid);
|
||||
|
||||
MXS_FREE(master_cfg);
|
||||
}
|
||||
@ -4454,6 +4570,11 @@ blr_master_set_empty_config(ROUTER_INSTANCE *router)
|
||||
router->binlog_position = 4;
|
||||
router->current_safe_event = 4;
|
||||
strcpy(router->binlog_name, "");
|
||||
strcpy(router->prevbinlog, "");
|
||||
/* Set Empty master id */
|
||||
router->orig_masterid = 0;
|
||||
/* Set Default GTID domain */
|
||||
router->mariadb10_gtid_domain = BLR_DEFAULT_GTID_DOMAIN_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4921,6 +5042,10 @@ static char
|
||||
{
|
||||
return &config->ssl_version;
|
||||
}
|
||||
else if (strcasecmp(option, "master_use_gtid") == 0)
|
||||
{
|
||||
return &config->use_mariadb10_gtid;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
@ -6547,6 +6672,7 @@ static GWBUF *blr_build_fake_rotate_event(ROUTER_SLAVE *slave,
|
||||
* @param req_pos The requested file pos
|
||||
* @return False if GTID is not found and slave
|
||||
* is connectig with gtid_strict_mode=1,
|
||||
* other errors.
|
||||
* True otherwise.
|
||||
*/
|
||||
static bool blr_slave_gtid_request(ROUTER_INSTANCE *router,
|
||||
@ -6581,16 +6707,29 @@ static bool blr_slave_gtid_request(ROUTER_INSTANCE *router,
|
||||
if (!slave->mariadb_gtid[0])
|
||||
{
|
||||
/**
|
||||
* Empty GTID:
|
||||
* Sending data from the router current file and pos 4
|
||||
*/
|
||||
* Empty GTID:
|
||||
* Sending data from the router current file and pos 4
|
||||
*/
|
||||
char t_prefix[BINLOG_FILE_EXTRA_INFO] = "";
|
||||
|
||||
// Add file prefix
|
||||
if (router->storage_type == BLR_BINLOG_STORAGE_TREE)
|
||||
{
|
||||
sprintf(t_prefix,
|
||||
"%" PRIu32 "/%" PRIu32 "/",
|
||||
f_gtid.gtid_elms.domain_id,
|
||||
f_gtid.gtid_elms.server_id);
|
||||
}
|
||||
|
||||
strcpy(slave->binlogfile, router_curr_file);
|
||||
slave->binlog_pos = 4;
|
||||
|
||||
MXS_INFO("Slave %lu is registering with empty GTID:"
|
||||
" sending events from current binlog file %s,"
|
||||
// TODO: Add prefix
|
||||
MXS_INFO("Slave %d is registering with empty GTID:"
|
||||
" sending events from current binlog file %s%s,"
|
||||
" pos %" PRIu32 "",
|
||||
(unsigned long)slave->serverid,
|
||||
slave->serverid,
|
||||
t_prefix,
|
||||
slave->binlogfile,
|
||||
slave->binlog_pos);
|
||||
|
||||
@ -7315,14 +7454,25 @@ static bool blr_handle_set_stmt(ROUTER_INSTANCE *router,
|
||||
1198, NULL);
|
||||
return false;
|
||||
}
|
||||
if (router->master_state != BLRM_SLAVE_STOPPED)
|
||||
if (router->master_state != BLRM_SLAVE_STOPPED &&
|
||||
router->master_state != BLRM_UNCONFIGURED)
|
||||
{
|
||||
MXS_ERROR("Master GTID registration needs stopped replication:"
|
||||
" issue STOP SLAVE first.");
|
||||
const char *err_msg_u = "configured replication: Issue CHANGE MASTER TO first.";
|
||||
const char *err_msg_s = "stopped replication: issue STOP SLAVE first.";
|
||||
char error_string[BINLOG_ERROR_MSG_LEN + 1] = "";
|
||||
MXS_ERROR("GTID registration without %s",
|
||||
router->master_state == BLRM_SLAVE_STOPPED ?
|
||||
err_msg_s : err_msg_u);
|
||||
|
||||
snprintf(error_string,
|
||||
BINLOG_ERROR_MSG_LEN,
|
||||
"Cannot use Master GTID registration without %s",
|
||||
router->master_state == BLRM_SLAVE_STOPPED ?
|
||||
err_msg_s :
|
||||
err_msg_u);
|
||||
|
||||
blr_slave_send_error_packet(slave,
|
||||
"Cannot use Master GTID registration"
|
||||
" with running replication;"
|
||||
" run STOP SLAVE first",
|
||||
error_string,
|
||||
1198,
|
||||
NULL);
|
||||
return true;
|
||||
@ -7518,7 +7668,7 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
MXS_ERROR("%s: %s", router->service->name, error_string);
|
||||
blr_slave_send_error_packet(slave,
|
||||
error_string,
|
||||
(unsigned int)1201,
|
||||
1201,
|
||||
NULL);
|
||||
|
||||
return true;
|
||||
@ -7573,7 +7723,7 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
{
|
||||
blr_slave_send_error_packet(slave,
|
||||
error_string,
|
||||
(unsigned int)1201,
|
||||
1201,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
@ -7593,7 +7743,7 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
blr_slave_send_error_packet(slave,
|
||||
"This operation cannot be performed "
|
||||
"with a running slave; run STOP SLAVE first",
|
||||
(unsigned int)1198,
|
||||
1198,
|
||||
NULL);
|
||||
}
|
||||
return true;
|
||||
@ -7661,7 +7811,7 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
{
|
||||
blr_slave_send_error_packet(slave,
|
||||
error_string,
|
||||
(unsigned int)1201,
|
||||
1201,
|
||||
NULL);
|
||||
|
||||
return true;
|
||||
@ -7676,7 +7826,7 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
/* CHANGE MASTER TO has failed */
|
||||
blr_slave_send_error_packet(slave,
|
||||
error_string,
|
||||
(unsigned int)1234,
|
||||
1234,
|
||||
"42000");
|
||||
blr_master_free_config(current_master);
|
||||
|
||||
@ -7709,7 +7859,7 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
|
||||
blr_slave_send_error_packet(slave,
|
||||
error_string,
|
||||
(unsigned int)1201,
|
||||
1201,
|
||||
NULL);
|
||||
|
||||
return true;
|
||||
@ -7730,10 +7880,13 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
/*
|
||||
* The binlog server has just been configured
|
||||
* master.ini file written in router->binlogdir.
|
||||
* Now create the binlogfile specified in MASTER_LOG_FILE
|
||||
*
|
||||
* Create the binlogfile specified in MASTER_LOG_FILE
|
||||
* only if MariaDB GTID 'mariadb10_master_gtid' is Off
|
||||
*/
|
||||
|
||||
if (blr_file_new_binlog(router, router->binlog_name))
|
||||
if (!router->mariadb10_master_gtid &&
|
||||
blr_file_new_binlog(router, router->binlog_name))
|
||||
{
|
||||
MXS_INFO("%s: 'master.ini' created, binlog file '%s' created",
|
||||
router->service->name, router->binlog_name);
|
||||
@ -7767,10 +7920,12 @@ static bool blr_handle_admin_stmt(ROUTER_INSTANCE *router,
|
||||
/*
|
||||
* The CHAMGE MASTER command might specify a new binlog file.
|
||||
* Let's create the binlogfile specified in MASTER_LOG_FILE
|
||||
* only if MariaDB GTID 'mariadb10_master_gtid' is Off
|
||||
*/
|
||||
|
||||
if (strlen(router->prevbinlog) &&
|
||||
strcmp(router->prevbinlog, router->binlog_name))
|
||||
if (!router->mariadb10_master_gtid &&
|
||||
(strlen(router->prevbinlog) &&
|
||||
strcmp(router->prevbinlog, router->binlog_name) != 0))
|
||||
{
|
||||
if (blr_file_new_binlog(router, router->binlog_name))
|
||||
{
|
||||
@ -7882,7 +8037,7 @@ static void blr_slave_skip_empty_files(ROUTER_INSTANCE *router,
|
||||
binlog_file);
|
||||
|
||||
// Update binlog_file name
|
||||
sprintf(binlog_file, next_file);
|
||||
strcpy(binlog_file, next_file);
|
||||
|
||||
// Get binlog file full-path
|
||||
blr_get_file_fullpath(binlog_file,
|
||||
@ -7950,7 +8105,7 @@ blr_show_binary_logs(ROUTER_INSTANCE *router,
|
||||
"server_id "
|
||||
"FROM gtid_maps "
|
||||
"GROUP BY binlog_file "
|
||||
"ORDER BY binlog_file ASC;";
|
||||
"ORDER BY id ASC;";
|
||||
int seqno;
|
||||
char *errmsg = NULL;
|
||||
BINARY_LOG_DATA_RESULT result = {};
|
||||
@ -8097,6 +8252,7 @@ GWBUF *blr_create_result_row(const char *val1,
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary logs select callback for sqlite3 database
|
||||
*
|
||||
|
Reference in New Issue
Block a user