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:
MassimilianoPinto
2015-09-15 15:13:05 +02:00
parent 6817db3ae1
commit abf5b6d02a
3 changed files with 194 additions and 4 deletions

View File

@ -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

View File

@ -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))));
}
}

View File

@ -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++);
}