MXS-2010 Introduce ChangeMasterConfig

This type will be used for storing the configuration
specified with CHANGE MASTER at a point where it has been
verified, to the extent possible, that the provided options
are valid.
This commit is contained in:
Johan Wikman
2018-08-23 16:21:10 +03:00
parent adb7bb8e8a
commit 883a3a6fe1
2 changed files with 141 additions and 14 deletions

View File

@ -342,29 +342,56 @@ typedef struct mariadb_gtid_info
} MARIADB_GTID_INFO;
/* Master Server configuration struct */
struct MasterServerConfig
class MasterServerConfig
{
std::string host;
public:
std::string host;
unsigned short port;
std::string logfile;
uint64_t pos;
uint64_t safe_pos;
std::string logfile;
uint64_t pos;
uint64_t safe_pos;
std::string user;
std::string password;
std::string filestem;
/* SSL options */
std::string ssl_key;
std::string ssl_cert;
std::string ssl_ca;
int ssl_enabled;
std::string ssl_version;
/* Connect options */
int heartbeat;
};
/* Config struct for CHANGE MASTER TO */
class ChangeMasterConfig
{
public:
std::string host;
int port;
std::string binlog_file;
std::string binlog_pos;
std::string user;
std::string password;
std::string filestem;
/* SSL options */
std::string ssl_key;
std::string ssl_cert;
std::string ssl_ca;
int ssl_enabled;
std::string ssl_enabled;
std::string ssl_version;
/* Connect options */
int heartbeat;
/* MariaDB 10 GTID */
std::string use_mariadb10_gtid;
/* Connection options */
int heartbeat_period;
int connect_retry;
};
struct ROUTER_INSTANCE;
/* Config struct for CHANGE MASTER TO options */
struct ChangeMasterOptions
class ChangeMasterOptions
{
public:
std::string host;
std::string port;
std::string binlog_file;
@ -382,6 +409,10 @@ struct ChangeMasterOptions
/* Connection options */
std::string heartbeat_period;
std::string connect_retry;
bool validate(ROUTER_INSTANCE* router,
char* error,
ChangeMasterConfig* config);
};
/**
@ -520,7 +551,7 @@ typedef struct router_slave
bool mariadb10_compat;/*< MariaDB 10.0 compatibility */
SPINLOCK rses_lock; /*< Protects rses_deleted */
pthread_t pthread;
struct router_instance *router; /*< Pointer to the owning router */
ROUTER_INSTANCE *router; /*< Pointer to the owning router */
struct router_slave *next;
SLAVE_STATS stats; /*< Slave statistics */
time_t connect_time; /*< Connect time of slave */
@ -658,7 +689,7 @@ typedef struct binlog_encryption_ctx
/**
* The per instance data for the router.
*/
typedef struct router_instance: public MXS_ROUTER
struct ROUTER_INSTANCE: public MXS_ROUTER
{
SERVICE *service; /*< Pointer to the service using this router */
ROUTER_SLAVE *slaves; /*< Link list of all the slave connections */
@ -756,8 +787,8 @@ typedef struct router_instance: public MXS_ROUTER
sqlite3 *gtid_maps; /*< MariaDB 10 GTID storage */
enum binlog_storage_type storage_type;/*< Enables hierachical binlog file storage */
char *set_slave_hostname; /*< Send custom Hostname to Master */
struct router_instance *next;
} ROUTER_INSTANCE;
ROUTER_INSTANCE *next;
};
/** Master Semi-Sync capability */
typedef enum

View File

@ -4128,6 +4128,102 @@ blr_slave_send_error_packet(ROUTER_SLAVE *slave,
MXS_SESSION_ROUTE_REPLY(slave->dcb->session, pkt);
}
bool ChangeMasterOptions::validate(ROUTER_INSTANCE* router,
char* error,
ChangeMasterConfig* config)
{
/* Abort if MASTER_USE_GTID is in use and
* router->mariadb10_master_gtid is not set
*/
if (!router->mariadb10_master_gtid && !this->use_mariadb10_gtid.empty())
{
snprintf(error,
BINLOG_ERROR_MSG_LEN,
"Cannot use MASTER_USE_GTID. "
"Enable 'mariadb10_master_gtid' option first.");
MXS_ERROR("%s: %s", router->service->name, error);
return false;
}
int heartbeat_period = -1;
if (!this->heartbeat_period.empty())
{
heartbeat_period = (int)strtol(this->heartbeat_period.c_str(), NULL, 10);
if (heartbeat_period < 0 ||
(errno == ERANGE) ||
heartbeat_period > BLR_HEARTBEAT_MAX_INTERVAL)
{
snprintf(error,
BINLOG_ERROR_MSG_LEN,
"The requested value for the heartbeat period is "
"either negative or exceeds the maximum allowed "
"(%d seconds).",
BLR_HEARTBEAT_MAX_INTERVAL);
MXS_ERROR("%s: %s", router->service->name, error);
return false;
}
}
int connect_retry = -1;
if (!this->connect_retry.empty())
{
connect_retry = (int)strtol(this->connect_retry.c_str(), NULL, 10);
if (connect_retry <= 0 ||
(errno == ERANGE))
{
snprintf(error,
BINLOG_ERROR_MSG_LEN,
"The requested value for MASTER_CONNECT_RETRY "
"interval is not valid: %s.",
this->connect_retry.c_str());
MXS_ERROR("%s: %s", router->service->name, error);
return false;
}
}
int port = -1;
if (!this->port.empty())
{
port = (int)strtol(this->port.c_str(), NULL, 10);
if ((port < 0) || (port > std::numeric_limits<unsigned short>::max()))
{
snprintf(error,
BINLOG_ERROR_MSG_LEN,
"The specified value for MASTER_PORT "
"is not valid: %s.",
this->port.c_str());
MXS_ERROR("%s: %s", router->service->name, error);
return false;
}
}
config->host = this->host;
config->port = port;
config->binlog_file = this->binlog_file;
config->binlog_pos = this->binlog_pos;
config->user = this->user;
config->password = this->password;
config->ssl_key = this->ssl_key;
config->ssl_cert = this->ssl_cert;
config->ssl_ca = this->ssl_ca;
config->ssl_enabled = this->ssl_enabled;
config->ssl_version = this->ssl_version;
config->use_mariadb10_gtid = this->use_mariadb10_gtid;
config->heartbeat_period = heartbeat_period;
config->connect_retry = connect_retry;
return true;
}
/**
* handle a 'change master' operation
*