Addition of status variable output formatting
Addition of status variable output formatting and router options check and check for mandatory server_id parameter Logging of binlog router identy seen by master and slaves
This commit is contained in:
@ -288,6 +288,8 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
inst->set_master_uuid = NULL;
|
||||
inst->set_master_server_id = NULL;
|
||||
|
||||
inst->serverid = 0;
|
||||
|
||||
my_uuid_init((ulong)rand()*12345,12345);
|
||||
if ((defuuid = (unsigned char *)malloc(20)) != NULL)
|
||||
{
|
||||
@ -332,9 +334,28 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
{
|
||||
inst->uuid = strdup(value);
|
||||
}
|
||||
else if (strcmp(options[i], "server-id") == 0)
|
||||
else if ( (strcmp(options[i], "server_id") == 0) || (strcmp(options[i], "server-id") == 0) )
|
||||
{
|
||||
inst->serverid = atoi(value);
|
||||
if (strcmp(options[i], "server-id") == 0) {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"WARNING: Configuration setting '%s' in router_options is deprecated"
|
||||
" and will be removed in a later version of MaxScale. "
|
||||
"Please use the new setting '%s' instead.",
|
||||
"server-id", "server_id")));
|
||||
}
|
||||
|
||||
if (inst->serverid <= 0) {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Service %s, invalid server-id '%s'. "
|
||||
"Please configure it with a unique positive integer value (1..2^32-1)",
|
||||
service->name, value)));
|
||||
|
||||
free(inst);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (strcmp(options[i], "user") == 0)
|
||||
{
|
||||
@ -348,13 +369,21 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
{
|
||||
inst->password = strdup(value);
|
||||
}
|
||||
else if (strcmp(options[i], "master-id") == 0)
|
||||
else if ( (strcmp(options[i], "master_id") == 0) || (strcmp(options[i], "master-id") == 0) )
|
||||
{
|
||||
int master_id = atoi(value);
|
||||
if (master_id > 0) {
|
||||
inst->masterid = master_id;
|
||||
inst->set_master_server_id = strdup(value);
|
||||
}
|
||||
if (strcmp(options[i], "master-id") == 0) {
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"WARNING: Configuration setting '%s' in router_options is deprecated"
|
||||
" and will be removed in a later version of MaxScale. "
|
||||
"Please use the new setting '%s' instead.",
|
||||
"master-id", "master_id")));
|
||||
}
|
||||
}
|
||||
else if (strcmp(options[i], "master_uuid") == 0)
|
||||
{
|
||||
@ -485,6 +514,14 @@ char task_name[BLRM_TASK_NAME_LEN+1] = "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (inst->serverid <= 0) {
|
||||
skygw_log_write_flush(LOGFILE_ERROR,
|
||||
"Error : Service %s, server-id is not configured. Please configure it with a unique positive integer value (1..2^32-1)",
|
||||
service->name, inst->serverid);
|
||||
free(inst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* If binlogdir is not found create it
|
||||
* On failure don't start the instance
|
||||
|
@ -98,6 +98,7 @@ GWBUF *blr_read_events_from_pos(ROUTER_INSTANCE *router, unsigned long long pos,
|
||||
static void blr_check_last_master_event(void *inst);
|
||||
extern int blr_check_heartbeat(ROUTER_INSTANCE *router);
|
||||
extern char * blr_last_event_description(ROUTER_INSTANCE *router);
|
||||
static void blr_log_identity(ROUTER_INSTANCE *router);
|
||||
|
||||
static int keepalive = 1;
|
||||
|
||||
@ -662,6 +663,9 @@ char task_name[BLRM_TASK_NAME_LEN + 1] = "";
|
||||
snprintf(task_name, BLRM_TASK_NAME_LEN, "%s heartbeat", router->service->name);
|
||||
hktask_add(task_name, blr_check_last_master_event, router, router->heartbeat);
|
||||
|
||||
/* Log binlog router identity */
|
||||
blr_log_identity(router);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2078,3 +2082,52 @@ char *event_desc = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void blr_log_identity(ROUTER_INSTANCE *router) {
|
||||
|
||||
char *master_uuid;
|
||||
char *master_hostname;
|
||||
char *master_version;
|
||||
|
||||
if (router->set_master_version)
|
||||
master_version = router->set_master_version;
|
||||
else {
|
||||
master_version = blr_extract_column(router->saved_master.selectver, 1);
|
||||
}
|
||||
if (router->set_master_hostname)
|
||||
master_hostname = router->set_master_hostname;
|
||||
else {
|
||||
master_hostname = blr_extract_column(router->saved_master.selecthostname, 1);
|
||||
}
|
||||
if (router->set_master_uuid)
|
||||
master_uuid = router->master_uuid;
|
||||
else {
|
||||
master_uuid = blr_extract_column(router->saved_master.uuid, 2);
|
||||
}
|
||||
|
||||
LOGIF(LT, (skygw_log_write_flush(
|
||||
LOGFILE_TRACE,
|
||||
"%s: identity seen by the master: "
|
||||
"server-id: %d, uuid: %s",
|
||||
router->service->name,
|
||||
router->serverid, (router->uuid == NULL ? "not available" : router->uuid))));
|
||||
|
||||
/* MariaDB 5.5 and MariaDB don't have the MASTER_UUID var */
|
||||
if (master_uuid == NULL) {
|
||||
LOGIF(LT, (skygw_log_write_flush(
|
||||
LOGFILE_TRACE,
|
||||
"%s: identity seen by the slaves: "
|
||||
"server-id: %d, hostname: %s, MySQL version: %s",
|
||||
router->service->name,
|
||||
router->masterid, (master_hostname == NULL ? "not available" : master_hostname),
|
||||
(master_version == NULL ? "not available" : master_version))));
|
||||
} else {
|
||||
LOGIF(LT, (skygw_log_write_flush(
|
||||
LOGFILE_TRACE,
|
||||
"%s: identity seen by the slaves: "
|
||||
"server-id: %d, uuid: %s, hostname: %s, MySQL version: %s",
|
||||
router->service->name,
|
||||
router->masterid, master_uuid,
|
||||
(master_hostname == NULL ? "not available" : master_hostname),
|
||||
(master_version == NULL ? "not available" : master_version))));
|
||||
}
|
||||
}
|
||||
|
@ -142,6 +142,8 @@ static int blr_slave_handle_variables(ROUTER_INSTANCE *router, ROUTER_SLAVE *sla
|
||||
static int blr_slave_send_warning_message(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave, char *message);
|
||||
static int blr_slave_show_warnings(ROUTER_INSTANCE* router, ROUTER_SLAVE* slave);
|
||||
extern int MaxScaleUptime();
|
||||
static int blr_slave_send_status_variable(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, char *variable, char *value, int column_type);
|
||||
static int blr_slave_handle_status_variables(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, char *stmt);
|
||||
|
||||
void poll_fake_write_event(DCB *dcb);
|
||||
|
||||
@ -493,7 +495,7 @@ extern char *strcasestr();
|
||||
else if (strcasecmp(word, "STATUS") == 0)
|
||||
{
|
||||
free(query_text);
|
||||
return blr_slave_handle_variables(router, slave, brkb);
|
||||
return blr_slave_handle_status_variables(router, slave, brkb);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(word, "VARIABLES") == 0)
|
||||
@ -569,7 +571,7 @@ extern char *strcasestr();
|
||||
else if (strcasecmp(word, "STATUS") == 0)
|
||||
{
|
||||
free(query_text);
|
||||
return blr_slave_handle_variables(router, slave, brkb);
|
||||
return blr_slave_handle_status_variables(router, slave, brkb);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(query_text, "SET") == 0)
|
||||
@ -4053,3 +4055,101 @@ int level_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the response to the SQL command "SHOW [GLOBAL] STATUS LIKE or SHOW STATUS LIKE
|
||||
*
|
||||
* @param router The binlog router instance
|
||||
* @param slave The slave server to which we are sending the response
|
||||
* @param stmt The SQL statement
|
||||
* @return Non-zero if the variable is handled, 0 if variable is unknown, -1 for syntax error
|
||||
*/
|
||||
static int
|
||||
blr_slave_handle_status_variables(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, char *stmt) {
|
||||
char *brkb;
|
||||
char *word;
|
||||
/* SPACE,TAB,= */
|
||||
char *sep = " ,=";
|
||||
|
||||
if ((word = strtok_r(stmt, sep, &brkb)) == NULL) {
|
||||
return 0;
|
||||
} else if (strcasecmp(word, "LIKE") == 0) {
|
||||
if ((word = strtok_r(NULL, sep, &brkb)) == NULL) {
|
||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||
"%s: Missing LIKE clause in SHOW [GLOBAL] VARIABLES.",
|
||||
router->service->name)));
|
||||
return 0;
|
||||
} else if (strcasecmp(word, "'Uptime'") == 0) {
|
||||
char uptime[41]="";
|
||||
snprintf(uptime, 40, "%d", MaxScaleUptime());
|
||||
return blr_slave_send_status_variable(router, slave, "Uptime", uptime, BLR_TYPE_INT);
|
||||
} else
|
||||
return 0;
|
||||
} else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send the response to the SQL command "SHOW [GLOBAL] STATUS LIKE 'xxx'
|
||||
*
|
||||
* @param router The binlog router instance
|
||||
* @param slave The slave server to which we are sending the response
|
||||
* @param variable The variable name
|
||||
* @param value The variable value
|
||||
* @param column_type The variable value type (string or int)
|
||||
* @return Non-zero if data was sent
|
||||
*/
|
||||
static int
|
||||
blr_slave_send_status_variable(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, char *variable, char *value, int column_type)
|
||||
{
|
||||
GWBUF *pkt;
|
||||
uint8_t *ptr;
|
||||
int len, vers_len, seqno = 2;
|
||||
char *p = strdup(variable);
|
||||
int var_len;
|
||||
char *old_ptr = p;
|
||||
|
||||
/* Remove heading and trailing "'" */
|
||||
if(*p == '\'')
|
||||
p++;
|
||||
if (p[strlen(p)-1] == '\'')
|
||||
p[strlen(p)-1] = '\0';
|
||||
|
||||
var_len = strlen(p);
|
||||
|
||||
/* force lowercase */
|
||||
for(int i = 0; i< var_len; i++) {
|
||||
p[i] = tolower(p[i]);
|
||||
}
|
||||
|
||||
/* First char is uppercase */
|
||||
p[0]=toupper(p[0]);
|
||||
|
||||
blr_slave_send_fieldcount(router, slave, 2);
|
||||
|
||||
blr_slave_send_columndef_with_info_schema(router, slave, "Variable_name", BLR_TYPE_STRING, 40, seqno++);
|
||||
blr_slave_send_columndef_with_info_schema(router, slave, "Value", column_type, 40, seqno++);
|
||||
|
||||
blr_slave_send_eof(router, slave, seqno++);
|
||||
|
||||
vers_len = strlen(value);
|
||||
len = 5 + vers_len + var_len + 1;
|
||||
if ((pkt = gwbuf_alloc(len)) == NULL)
|
||||
return 0;
|
||||
ptr = GWBUF_DATA(pkt);
|
||||
encode_value(ptr, vers_len + 2 + var_len, 24); // Add length of data packet
|
||||
ptr += 3;
|
||||
*ptr++ = seqno++; // Sequence number in response
|
||||
*ptr++ = var_len; // Length of result string
|
||||
strncpy((char *)ptr, p, var_len); // Result string with var name
|
||||
ptr += var_len;
|
||||
*ptr++ = vers_len; // Length of result string
|
||||
strncpy((char *)ptr, value, vers_len); // Result string with var value
|
||||
ptr += vers_len;
|
||||
slave->dcb->func.write(slave->dcb, pkt);
|
||||
|
||||
free(old_ptr);
|
||||
|
||||
return blr_slave_send_eof(router, slave, seqno++);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user