Merge branch 'develop' into 1.2.1-binlog_router
Conflicts: server/core/server.c server/include/server.h server/modules/include/blr.h server/modules/routing/binlog/blr.c server/modules/routing/binlog/blr_file.c server/modules/routing/binlog/blr_master.c server/modules/routing/binlog/blr_slave.c
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
add_library(binlogrouter SHARED blr.c blr_master.c blr_cache.c blr_slave.c blr_file.c)
|
||||
set_target_properties(binlogrouter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/lib)
|
||||
set_target_properties(binlogrouter PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${MAXSCALE_LIBDIR})
|
||||
target_link_libraries(binlogrouter ssl pthread log_manager)
|
||||
install(TARGETS binlogrouter DESTINATION modules)
|
||||
install(TARGETS binlogrouter DESTINATION ${MAXSCALE_LIBDIR})
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
* 02/04/2014 Mark Riddoch Initial implementation
|
||||
* 17/02/2015 Massimiliano Pinto Addition of slave port and username in diagnostics
|
||||
* 18/02/2015 Massimiliano Pinto Addition of dcb_close in closeSession
|
||||
* 07/05/2015 Massimiliano Pinto Addition of MariaDB 10 compatibility support
|
||||
* 12/06/2015 Massimiliano Pinto Addition of MariaDB 10 events in diagnostics()
|
||||
* 29/06/2015 Massimiliano Pinto Addition of master.ini for easy startup configuration
|
||||
* If not found router goes into BLRM_UNCONFIGURED state.
|
||||
* Cache dir is 'cache' under router->binlogdir.
|
||||
@ -117,6 +119,9 @@ static void stats_func(void *);
|
||||
|
||||
static bool rses_begin_locked_router_action(ROUTER_SLAVE *);
|
||||
static void rses_end_locked_router_action(ROUTER_SLAVE *);
|
||||
void my_uuid_init(ulong seed1, ulong seed2);
|
||||
void my_uuid(char *guid);
|
||||
GWBUF *blr_cache_read_response(ROUTER_INSTANCE *router, char *response);
|
||||
|
||||
static SPINLOCK instlock;
|
||||
static ROUTER_INSTANCE *instances;
|
||||
@ -184,8 +189,45 @@ char path[PATH_MAX+1] = "";
|
||||
char filename[PATH_MAX+1] = "";
|
||||
int master_info = 0;
|
||||
int rc = 0;
|
||||
char *defuuid;
|
||||
|
||||
if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) {
|
||||
if(service->credentials.name == NULL ||
|
||||
service->credentials.authdata == NULL)
|
||||
{
|
||||
skygw_log_write(LE,"%s: Error: Service is missing user credentials."
|
||||
" Add the missing username or passwd parameter to the service.",
|
||||
service->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(options == NULL || options[0] == NULL)
|
||||
{
|
||||
skygw_log_write(LE,
|
||||
"%s: Error: No router options supplied for binlogrouter",
|
||||
service->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We only support one server behind this router, since the server is
|
||||
* the master from which we replicate binlog records. Therefore check
|
||||
* that only one server has been defined.
|
||||
*
|
||||
* A later improvement will be to define multiple servers and have the
|
||||
* router use the information that is supplied by the monitor to find
|
||||
* which of these servers is currently the master and replicate from
|
||||
* that server.
|
||||
*/
|
||||
if (service->dbref == NULL || service->dbref->next != NULL)
|
||||
{
|
||||
skygw_log_write(LE,
|
||||
"%s: Error : Exactly one database server may be "
|
||||
"for use with the binlog router.",
|
||||
service->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((inst = calloc(1, sizeof(ROUTER_INSTANCE))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -215,6 +257,7 @@ int rc = 0;
|
||||
inst->retry_backoff = 1;
|
||||
inst->binlogdir = NULL;
|
||||
inst->heartbeat = 300; // Default is every 5 minutes
|
||||
inst->mariadb10_compat = false;
|
||||
|
||||
inst->user = strdup(service->credentials.name);
|
||||
inst->password = strdup(service->credentials.authdata);
|
||||
@ -234,22 +277,6 @@ int rc = 0;
|
||||
defuuid[12], defuuid[13], defuuid[14], defuuid[15]);
|
||||
}
|
||||
|
||||
/*
|
||||
* We only support one server behind this router, since the server is
|
||||
* the master from which we replicate binlog records. Therefore check
|
||||
* that only one server has been defined.
|
||||
*
|
||||
*/
|
||||
|
||||
if (service->dbref && service->dbref->next != NULL)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"Error : Exactly one database server may be "
|
||||
"for use with the binlog router.")));
|
||||
/* report as error whether a server is defined in the service */
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the options.
|
||||
* We have an array of attribute values passed to us that we must
|
||||
@ -302,6 +329,10 @@ int rc = 0;
|
||||
{
|
||||
inst->masterid = atoi(value);
|
||||
}
|
||||
else if (strcmp(options[i], "mariadb10-compatibility") == 0)
|
||||
{
|
||||
inst->mariadb10_compat = config_truth_value(value);
|
||||
}
|
||||
else if (strcmp(options[i], "filestem") == 0)
|
||||
{
|
||||
inst->fileroot = strdup(value);
|
||||
@ -376,7 +407,7 @@ int rc = 0;
|
||||
else
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write(
|
||||
LOGFILE_ERROR, "%s: No router options supplied for binlogrouter",
|
||||
LOGFILE_ERROR, "%s: Error: No router options supplied for binlogrouter",
|
||||
service->name)));
|
||||
}
|
||||
|
||||
@ -508,6 +539,7 @@ int rc = 0;
|
||||
/*
|
||||
* Read any cached response messages
|
||||
*/
|
||||
|
||||
blr_cache_read_master_data(inst);
|
||||
|
||||
/*
|
||||
@ -627,6 +659,7 @@ ROUTER_SLAVE *slave;
|
||||
strcpy(slave->binlogfile, "unassigned");
|
||||
slave->connect_time = time(0);
|
||||
slave->lastEventTimestamp = 0;
|
||||
slave->mariadb10_compat = false;
|
||||
|
||||
/**
|
||||
* Add this session to the list of active sessions.
|
||||
@ -810,6 +843,15 @@ static char *event_names[] = {
|
||||
"Anonymous GTID Event", "Previous GTIDS Event"
|
||||
};
|
||||
|
||||
/* New MariaDB event numbers starts from 0xa0 */
|
||||
static char *event_names_mariadb10[] = {
|
||||
"Annotate Rows Event",
|
||||
/* New MariaDB 10.x event numbers */
|
||||
"Binlog Checkpoint Event",
|
||||
"GTID Event",
|
||||
"GTID List Event"
|
||||
};
|
||||
|
||||
/**
|
||||
* Display an entry from the spinlock statistics data
|
||||
*
|
||||
@ -929,14 +971,31 @@ struct tm tm;
|
||||
buf);
|
||||
dcb_printf(dcb, "\t (%d seconds ago)\n",
|
||||
time(0) - router_inst->stats.lastReply);
|
||||
dcb_printf(dcb, "\tLast event from master: 0x%x, %s",
|
||||
|
||||
if (!router_inst->mariadb10_compat) {
|
||||
dcb_printf(dcb, "\tLast event from master: 0x%x, %s",
|
||||
router_inst->lastEventReceived,
|
||||
(router_inst->lastEventReceived >= 0 &&
|
||||
router_inst->lastEventReceived < 0x24) ?
|
||||
router_inst->lastEventReceived <= MAX_EVENT_TYPE) ?
|
||||
event_names[router_inst->lastEventReceived] : "unknown");
|
||||
} else {
|
||||
char *ptr = NULL;
|
||||
if (router_inst->lastEventReceived >= 0 && router_inst->lastEventReceived <= MAX_EVENT_TYPE) {
|
||||
ptr = event_names[router_inst->lastEventReceived];
|
||||
} else {
|
||||
/* Check MariaDB 10 new events */
|
||||
if (router_inst->lastEventReceived >= MARIADB_NEW_EVENTS_BEGIN && router_inst->lastEventReceived <= MAX_EVENT_TYPE_MARIADB10) {
|
||||
ptr = event_names_mariadb10[(router_inst->lastEventReceived - MARIADB_NEW_EVENTS_BEGIN)];
|
||||
}
|
||||
}
|
||||
|
||||
dcb_printf(dcb, "\tLast event from master: 0x%x, %s",
|
||||
router_inst->lastEventReceived, (ptr != NULL) ? ptr : "unknown");
|
||||
}
|
||||
|
||||
if (router_inst->lastEventTimestamp)
|
||||
{
|
||||
localtime_r(&router_inst->lastEventTimestamp, &tm);
|
||||
localtime_r((const time_t*)&router_inst->lastEventTimestamp, &tm);
|
||||
asctime_r(&tm, buf);
|
||||
dcb_printf(dcb, "\tLast binlog event timestamp: %ld (%s)\n",
|
||||
router_inst->lastEventTimestamp, buf);
|
||||
@ -946,11 +1005,17 @@ struct tm tm;
|
||||
if (router_inst->reconnect_pending)
|
||||
dcb_printf(dcb, "\tRouter pending reconnect to master\n");
|
||||
dcb_printf(dcb, "\tEvents received:\n");
|
||||
for (i = 0; i < 0x24; i++)
|
||||
for (i = 0; i <= MAX_EVENT_TYPE; i++)
|
||||
{
|
||||
dcb_printf(dcb, "\t\t%-38s %u\n", event_names[i], router_inst->stats.events[i]);
|
||||
}
|
||||
|
||||
if (router_inst->mariadb10_compat) {
|
||||
/* Display MariaDB 10 new events */
|
||||
for (i = MARIADB_NEW_EVENTS_BEGIN; i <= MAX_EVENT_TYPE_MARIADB10; i++)
|
||||
dcb_printf(dcb, "\t\tMariaDB 10 %-38s %u\n", event_names_mariadb10[(i - MARIADB_NEW_EVENTS_BEGIN)], router_inst->stats.events[i]);
|
||||
}
|
||||
|
||||
#if SPINLOCK_PROFILE
|
||||
dcb_printf(dcb, "\tSpinlock statistics (instlock):\n");
|
||||
spinlock_stats(&instlock, spin_reporter, dcb);
|
||||
@ -1058,7 +1123,7 @@ struct tm tm;
|
||||
if (session->lastEventTimestamp
|
||||
&& router_inst->lastEventTimestamp)
|
||||
{
|
||||
localtime_r(&session->lastEventTimestamp, &tm);
|
||||
localtime_r((const time_t*)&session->lastEventTimestamp, &tm);
|
||||
asctime_r(&tm, buf);
|
||||
dcb_printf(dcb, "\t\tLast binlog event timestamp %u, %s", session->lastEventTimestamp, buf);
|
||||
dcb_printf(dcb, "\t\tSeconds behind master %u\n", router_inst->lastEventTimestamp - session->lastEventTimestamp);
|
||||
@ -1156,7 +1221,8 @@ static void
|
||||
errorReply(ROUTER *instance, void *router_session, GWBUF *message, DCB *backend_dcb, error_action_t action, bool *succp)
|
||||
{
|
||||
ROUTER_INSTANCE *router = (ROUTER_INSTANCE *)instance;
|
||||
int error, len;
|
||||
int error;
|
||||
socklen_t len;
|
||||
char msg[85], *errmsg;
|
||||
unsigned long mysql_errno;
|
||||
|
||||
@ -1329,10 +1395,10 @@ unsigned long len;
|
||||
|
||||
snprintf(result, 1000,
|
||||
"Uptime: %u Threads: %u Events: %u Slaves: %u Master State: %s",
|
||||
time(0) - router->connect_time,
|
||||
config_threadcount(),
|
||||
router->stats.n_binlogs_ses,
|
||||
router->stats.n_slaves,
|
||||
(unsigned int)(time(0) - router->connect_time),
|
||||
(unsigned int)config_threadcount(),
|
||||
(unsigned int)router->stats.n_binlogs_ses,
|
||||
(unsigned int)router->stats.n_slaves,
|
||||
blrm_states[router->master_state]);
|
||||
if ((ret = gwbuf_alloc(4 + strlen(result))) == NULL)
|
||||
return 0;
|
||||
@ -1684,5 +1750,24 @@ int mkdir_rval;
|
||||
strncat(path, "/dbusers", PATH_MAX);
|
||||
|
||||
return dbusers_save(service->users, path);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a numeric field from a packet of the specified number of bits
|
||||
*
|
||||
* @param src The raw packet source
|
||||
* @param birs The number of bits to extract (multiple of 8)
|
||||
*/
|
||||
uint32_t
|
||||
extract_field(uint8_t *src, int bits)
|
||||
{
|
||||
uint32_t rval = 0, shift = 0;
|
||||
|
||||
while (bits > 0)
|
||||
{
|
||||
rval |= (*src++) << shift;
|
||||
shift += 8;
|
||||
bits -= 8;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
*
|
||||
* Date Who Description
|
||||
* 14/04/2014 Mark Riddoch Initial implementation
|
||||
* 07/05/2015 Massimiliano Pinto Added MAX_EVENT_TYPE_MARIADB10
|
||||
* 08/06/2015 Massimiliano Pinto Addition of blr_cache_read_master_data()
|
||||
* 15/06/2015 Massimiliano Pinto Addition of blr_file_get_next_binlogname()
|
||||
* 23/06/2015 Massimiliano Pinto Addition of blr_file_use_binlog, blr_file_create_binlog
|
||||
@ -50,7 +51,7 @@
|
||||
#include <blr.h>
|
||||
#include <dcb.h>
|
||||
#include <spinlock.h>
|
||||
|
||||
#include <gwdirs.h>
|
||||
#include <skygw_types.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
@ -62,7 +63,6 @@ extern __thread log_info_t tls_log_info;
|
||||
|
||||
static int blr_file_create(ROUTER_INSTANCE *router, char *file);
|
||||
static void blr_file_append(ROUTER_INSTANCE *router, char *file);
|
||||
static uint32_t extract_field(uint8_t *src, int bits);
|
||||
static void blr_log_header(logfile_id_t file, char *msg, uint8_t *ptr);
|
||||
void blr_cache_read_master_data(ROUTER_INSTANCE *router);
|
||||
int blr_file_get_next_binlogname(ROUTER_INSTANCE *router);
|
||||
@ -81,7 +81,7 @@ int blr_file_write_master_config(ROUTER_INSTANCE *router, char *error);
|
||||
int
|
||||
blr_file_init(ROUTER_INSTANCE *router)
|
||||
{
|
||||
char *ptr, path[PATH_MAX], filename[PATH_MAX];
|
||||
char *ptr, path[PATH_MAX+1], filename[PATH_MAX+1];
|
||||
int file_found, n = 1;
|
||||
int root_len, i;
|
||||
DIR *dirp;
|
||||
@ -89,12 +89,8 @@ struct dirent *dp;
|
||||
|
||||
if (router->binlogdir == NULL)
|
||||
{
|
||||
strcpy(path, "/usr/local/mariadb-maxscale");
|
||||
if ((ptr = getenv("MAXSCALE_HOME")) != NULL)
|
||||
{
|
||||
strncpy(path, ptr,PATH_MAX);
|
||||
}
|
||||
strncat(path, "/",PATH_MAX);
|
||||
strcpy(path, get_datadir());
|
||||
strncat(path,"/",PATH_MAX);
|
||||
strncat(path, router->service->name,PATH_MAX);
|
||||
|
||||
if (access(path, R_OK) == -1)
|
||||
@ -452,15 +448,26 @@ struct stat statb;
|
||||
hdr->next_pos = EXTRACT32(&hdbuf[13]);
|
||||
hdr->flags = EXTRACT16(&hdbuf[17]);
|
||||
|
||||
if (hdr->event_type > MAX_EVENT_TYPE)
|
||||
{
|
||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||
"Invalid event type 0x%x. "
|
||||
if (router->mariadb10_compat) {
|
||||
if (hdr->event_type > MAX_EVENT_TYPE_MARIADB10) {
|
||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||
"Invalid MariaDB 10 event type 0x%x. "
|
||||
"Binlog file is %s, position %d",
|
||||
hdr->event_type,
|
||||
file->binlogname, pos)));
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (hdr->event_type > MAX_EVENT_TYPE) {
|
||||
LOGIF(LE, (skygw_log_write(LOGFILE_ERROR,
|
||||
"Invalid event type 0x%x. "
|
||||
"Binlog file is %s, position %d",
|
||||
hdr->event_type,
|
||||
file->binlogname, pos)));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (hdr->next_pos < pos && hdr->event_type != ROTATE_EVENT)
|
||||
{
|
||||
@ -600,26 +607,6 @@ blr_close_binlog(ROUTER_INSTANCE *router, BLFILE *file)
|
||||
free(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a numeric field from a packet of the specified number of bits
|
||||
*
|
||||
* @param src The raw packet source
|
||||
* @param birs The number of bits to extract (multiple of 8)
|
||||
*/
|
||||
static uint32_t
|
||||
extract_field(uint8_t *src, int bits)
|
||||
{
|
||||
uint32_t rval = 0, shift = 0;
|
||||
|
||||
while (bits > 0)
|
||||
{
|
||||
rval |= (*src++) << shift;
|
||||
shift += 8;
|
||||
bits -= 8;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the event header of binlog event
|
||||
*
|
||||
@ -671,10 +658,10 @@ struct stat statb;
|
||||
void
|
||||
blr_cache_response(ROUTER_INSTANCE *router, char *response, GWBUF *buf)
|
||||
{
|
||||
char path[4097], *ptr;
|
||||
char path[PATH_MAX+1], *ptr;
|
||||
int fd;
|
||||
|
||||
strncpy(path, router->binlogdir, 4096);
|
||||
strncpy(path, router->binlogdir, PATH_MAX);
|
||||
strncat(path, "/cache", 4096);
|
||||
|
||||
if (access(path, R_OK) == -1) {
|
||||
@ -682,8 +669,8 @@ int fd;
|
||||
mkdir_ret = mkdir(path, 0700);
|
||||
}
|
||||
|
||||
strncat(path, "/", 4096);
|
||||
strncat(path, response, 4096);
|
||||
strncat(path, "/", PATH_MAX);
|
||||
strncat(path, response, PATH_MAX);
|
||||
|
||||
if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1)
|
||||
return;
|
||||
@ -707,14 +694,14 @@ GWBUF *
|
||||
blr_cache_read_response(ROUTER_INSTANCE *router, char *response)
|
||||
{
|
||||
struct stat statb;
|
||||
char path[4097], *ptr;
|
||||
char path[PATH_MAX+1], *ptr;
|
||||
int fd;
|
||||
GWBUF *buf;
|
||||
|
||||
strncpy(path, router->binlogdir, 4096);
|
||||
strncat(path, "/cache", 4096);
|
||||
strncat(path, "/", 4096);
|
||||
strncat(path, response, 4096);
|
||||
strncpy(path, router->binlogdir, PATH_MAX);
|
||||
strncat(path, "/cache", PATH_MAX);
|
||||
strncat(path, "/", PATH_MAX);
|
||||
strncat(path, response, PATH_MAX);
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) == -1)
|
||||
return NULL;
|
||||
|
||||
@ -32,12 +32,13 @@
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 02/04/2014 Mark Riddoch Initial implementation
|
||||
* 25/05/2015 Massimiliano Pinto Added BLRM_SLAVE_STOPPED state
|
||||
* 08/06/2015 Massimiliano Pinto Added m_errno and m_errmsg
|
||||
* 23/06/2015 Massimiliano Pinto Master communication goes into BLRM_SLAVE_STOPPED state
|
||||
* when an error is encountered in BLRM_BINLOGDUMP state.
|
||||
* Server error code and msg are reported via SHOW SLAVE STATUS
|
||||
* 02/04/2014 Mark Riddoch Initial implementation
|
||||
* 07/05/2015 Massimiliano Pinto Added MariaDB 10 Compatibility
|
||||
* 25/05/2015 Massimiliano Pinto Added BLRM_SLAVE_STOPPED state
|
||||
* 08/06/2015 Massimiliano Pinto Added m_errno and m_errmsg
|
||||
* 23/06/2015 Massimiliano Pinto Master communication goes into BLRM_SLAVE_STOPPED state
|
||||
* when an error is encountered in BLRM_BINLOGDUMP state.
|
||||
* Server error code and msg are reported via SHOW SLAVE STATUS
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
@ -81,11 +82,11 @@ static int blr_rotate_event(ROUTER_INSTANCE *router, uint8_t *pkt, REP_HEADER *
|
||||
void blr_distribute_binlog_record(ROUTER_INSTANCE *router, REP_HEADER *hdr, uint8_t *ptr);
|
||||
static void *CreateMySQLAuthData(char *username, char *password, char *database);
|
||||
void blr_extract_header(uint8_t *pkt, REP_HEADER *hdr);
|
||||
inline uint32_t extract_field(uint8_t *src, int bits);
|
||||
static void blr_log_packet(logfile_id_t file, char *msg, uint8_t *ptr, int len);
|
||||
void blr_master_close(ROUTER_INSTANCE *);
|
||||
static char *blr_extract_column(GWBUF *buf, int col);
|
||||
|
||||
void blr_cache_response(ROUTER_INSTANCE *router, char *response, GWBUF *buf);
|
||||
void poll_fake_write_event(DCB *dcb);
|
||||
static int keepalive = 1;
|
||||
|
||||
/**
|
||||
@ -96,8 +97,9 @@ static int keepalive = 1;
|
||||
* @param router The router instance
|
||||
*/
|
||||
void
|
||||
blr_start_master(ROUTER_INSTANCE *router)
|
||||
blr_start_master(void* data)
|
||||
{
|
||||
ROUTER_INSTANCE *router = (ROUTER_INSTANCE*)data;
|
||||
DCB *client;
|
||||
GWBUF *buf;
|
||||
|
||||
@ -488,11 +490,27 @@ char query[128];
|
||||
GWBUF_CONSUME_ALL(router->saved_master.chksum2);
|
||||
router->saved_master.chksum2 = buf;
|
||||
blr_cache_response(router, "chksum2", buf);
|
||||
buf = blr_make_query("SELECT @@GLOBAL.GTID_MODE");
|
||||
router->master_state = BLRM_GTIDMODE;
|
||||
|
||||
if (router->mariadb10_compat) {
|
||||
buf = blr_make_query("SET @mariadb_slave_capability=4");
|
||||
router->master_state = BLRM_MARIADB10;
|
||||
} else {
|
||||
buf = blr_make_query("SELECT @@GLOBAL.GTID_MODE");
|
||||
router->master_state = BLRM_GTIDMODE;
|
||||
}
|
||||
router->master->func.write(router->master, buf);
|
||||
break;
|
||||
}
|
||||
case BLRM_MARIADB10:
|
||||
// Response to the SET @mariadb_slave_capability=4, should be stored
|
||||
if (router->saved_master.mariadb10)
|
||||
GWBUF_CONSUME_ALL(router->saved_master.mariadb10);
|
||||
router->saved_master.mariadb10 = buf;
|
||||
blr_cache_response(router, "mariadb10", buf);
|
||||
buf = blr_make_query("SHOW VARIABLES LIKE 'SERVER_UUID'");
|
||||
router->master_state = BLRM_MUUID;
|
||||
router->master->func.write(router->master, buf);
|
||||
break;
|
||||
case BLRM_GTIDMODE:
|
||||
// Response to the GTID_MODE, should be stored
|
||||
if (router->saved_master.gtid_mode)
|
||||
@ -763,7 +781,6 @@ int no_residual = 1;
|
||||
int preslen = -1;
|
||||
int prev_length = -1;
|
||||
int n_bufs = -1, pn_bufs = -1;
|
||||
static REP_HEADER phdr;
|
||||
|
||||
/*
|
||||
* Prepend any residual buffer to the buffer chain we have
|
||||
@ -950,7 +967,7 @@ static REP_HEADER phdr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
phdr = hdr;
|
||||
|
||||
if (hdr.ok == 0)
|
||||
{
|
||||
/* set mysql errno to 0 */
|
||||
@ -961,6 +978,8 @@ static REP_HEADER phdr;
|
||||
free(router->m_errmsg);
|
||||
router->m_errmsg = NULL;
|
||||
|
||||
int event_limit;
|
||||
|
||||
/*
|
||||
* First check that the checksum we calculate matches the
|
||||
* checksum in the packet we received.
|
||||
@ -1001,8 +1020,11 @@ static REP_HEADER phdr;
|
||||
#ifdef SHOW_EVENTS
|
||||
printf("blr: event type 0x%02x, flags 0x%04x, event size %d", hdr.event_type, hdr.flags, hdr.event_size);
|
||||
#endif
|
||||
if (hdr.event_type >= 0 && hdr.event_type < 0x24)
|
||||
event_limit = router->mariadb10_compat ? MAX_EVENT_TYPE_MARIADB10 : MAX_EVENT_TYPE;
|
||||
|
||||
if (hdr.event_type >= 0 && hdr.event_type <= event_limit)
|
||||
router->stats.events[hdr.event_type]++;
|
||||
|
||||
if (hdr.event_type == FORMAT_DESCRIPTION_EVENT && hdr.next_pos == 0)
|
||||
{
|
||||
// Fake format description message
|
||||
@ -1224,26 +1246,6 @@ blr_extract_header(register uint8_t *ptr, register REP_HEADER *hdr)
|
||||
hdr->flags = EXTRACT16(&ptr[22]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a numeric field from a packet of the specified number of bits
|
||||
*
|
||||
* @param src The raw packet source
|
||||
* @param bits The number of bits to extract (multiple of 8)
|
||||
*/
|
||||
inline uint32_t
|
||||
extract_field(register uint8_t *src, int bits)
|
||||
{
|
||||
register uint32_t rval = 0, shift = 0;
|
||||
|
||||
while (bits > 0)
|
||||
{
|
||||
rval |= (*src++) << shift;
|
||||
shift += 8;
|
||||
bits -= 8;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a binlog rotate event.
|
||||
*
|
||||
@ -1313,8 +1315,8 @@ MYSQL_session *auth_info;
|
||||
|
||||
if ((auth_info = calloc(1, sizeof(MYSQL_session))) == NULL)
|
||||
return NULL;
|
||||
strncpy(auth_info->user, username,MYSQL_USER_MAXLEN+1);
|
||||
strncpy(auth_info->db, database,MYSQL_DATABASE_MAXLEN+1);
|
||||
strncpy(auth_info->user, username,MYSQL_USER_MAXLEN);
|
||||
strncpy(auth_info->db, database,MYSQL_DATABASE_MAXLEN);
|
||||
gw_sha1_str((const uint8_t *)password, strlen(password), auth_info->client_sha1);
|
||||
|
||||
return auth_info;
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
* 18/02/2015 Massimiliano Pinto Addition of DISCONNECT ALL and DISCONNECT SERVER server_id
|
||||
* 18/03/2015 Markus Makela Better detection of CRC32 | NONE checksum
|
||||
* 19/03/2015 Massimiliano Pinto Addition of basic MariaDB 10 compatibility support
|
||||
* 07/05/2015 Massimiliano Pinto Added MariaDB 10 Compatibility
|
||||
* 11/05/2015 Massimiliano Pinto Only MariaDB 10 Slaves can register to binlog router with a MariaDB 10 Master
|
||||
* 25/05/2015 Massimiliano Pinto Addition of BLRM_SLAVE_STOPPED state and blr_start/stop_slave.
|
||||
* New commands STOP SLAVE, START SLAVE added.
|
||||
* 29/05/2015 Massimiliano Pinto Addition of CHANGE MASTER TO ...
|
||||
@ -48,6 +50,7 @@
|
||||
*
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
@ -115,6 +118,8 @@ static void blr_master_restore_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG
|
||||
static void blr_master_set_empty_config(ROUTER_INSTANCE *router);
|
||||
static void blr_master_apply_config(ROUTER_INSTANCE *router, MASTER_SERVER_CFG *prev_master);
|
||||
|
||||
void poll_fake_write_event(DCB *dcb);
|
||||
|
||||
extern int lm_enabled_logfiles_bitmask;
|
||||
extern size_t log_ses_count[];
|
||||
extern __thread log_info_t tls_log_info;
|
||||
@ -166,7 +171,28 @@ blr_slave_request(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
slave->dcb->remote)));
|
||||
dcb_close(slave->dcb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If Master is MariaDB10 don't allow registration from
|
||||
* MariaDB/Mysql 5 Slaves
|
||||
*/
|
||||
|
||||
if (router->mariadb10_compat && !slave->mariadb10_compat) {
|
||||
slave->state = BLRS_ERRORED;
|
||||
blr_send_custom_error(slave->dcb, 1, 0,
|
||||
"MariaDB 10 Slave is required for Slave registration");
|
||||
|
||||
LOGIF(LE, (skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"%s: Slave %s: a MariaDB 10 Slave is required for Slave registration",
|
||||
router->service->name,
|
||||
slave->dcb->remote)));
|
||||
|
||||
dcb_close(slave->dcb);
|
||||
return 1;
|
||||
} else {
|
||||
/* Master and Slave version OK: continue with slave registration */
|
||||
return blr_slave_register(router, slave, queue);
|
||||
}
|
||||
break;
|
||||
@ -455,10 +481,17 @@ extern char *strcasestr();
|
||||
free(query_text);
|
||||
return blr_slave_replay(router, slave, router->saved_master.heartbeat);
|
||||
}
|
||||
else if (strcasecmp(word, "@mariadb_slave_capability") == 0)
|
||||
else if (strcasecmp(word, "@mariadb_slave_capability") == 0)
|
||||
{
|
||||
free(query_text);
|
||||
return blr_slave_send_ok(router, slave);
|
||||
/* mariadb10 compatibility is set for the slave */
|
||||
slave->mariadb10_compat=true;
|
||||
|
||||
free(query_text);
|
||||
if (router->mariadb10_compat) {
|
||||
return blr_slave_replay(router, slave, router->saved_master.mariadb10);
|
||||
} else {
|
||||
return blr_slave_send_ok(router, slave);
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(word, "@master_binlog_checksum") == 0)
|
||||
{
|
||||
@ -1404,10 +1437,9 @@ blr_slave_register(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue)
|
||||
{
|
||||
GWBUF *resp;
|
||||
uint8_t *ptr;
|
||||
int len, slen;
|
||||
int slen;
|
||||
|
||||
ptr = GWBUF_DATA(queue);
|
||||
len = extract_field(ptr, 24);
|
||||
ptr += 4; // Skip length and sequence number
|
||||
if (*ptr++ != COM_REGISTER_SLAVE)
|
||||
return 0;
|
||||
@ -1476,7 +1508,7 @@ blr_slave_binlog_dump(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave, GWBUF *queue
|
||||
{
|
||||
GWBUF *resp;
|
||||
uint8_t *ptr;
|
||||
int len, flags, serverid, rval, binlognamelen;
|
||||
int len, rval, binlognamelen;
|
||||
REP_HEADER hdr;
|
||||
uint32_t chksum;
|
||||
|
||||
@ -1504,9 +1536,7 @@ uint32_t chksum;
|
||||
|
||||
slave->binlog_pos = extract_field(ptr, 32);
|
||||
ptr += 4;
|
||||
flags = extract_field(ptr, 16);
|
||||
ptr += 2;
|
||||
serverid = extract_field(ptr, 32);
|
||||
ptr += 4;
|
||||
strncpy(slave->binlogfile, (char *)ptr, binlognamelen);
|
||||
slave->binlogfile[binlognamelen] = 0;
|
||||
@ -1588,28 +1618,6 @@ uint32_t chksum;
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a numeric field from a packet of the specified number of bits,
|
||||
* the number of bits must be a multiple of 8.
|
||||
*
|
||||
* @param src The raw packet source
|
||||
* @param bits The number of bits to extract (multiple of 8)
|
||||
* @return The extracted value
|
||||
*/
|
||||
static uint32_t
|
||||
extract_field(uint8_t *src, int bits)
|
||||
{
|
||||
uint32_t rval = 0, shift = 0;
|
||||
|
||||
while (bits > 0)
|
||||
{
|
||||
rval |= (*src++) << shift;
|
||||
shift += 8;
|
||||
bits -= 8;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a value into a number of bits in a MySQL packet
|
||||
*
|
||||
@ -1971,7 +1979,7 @@ int len = EXTRACT24(ptr + 9); // Extract the event length
|
||||
len = BINLOG_FNAMELEN;
|
||||
ptr += 19; // Skip header
|
||||
slave->binlog_pos = extract_field(ptr, 32);
|
||||
slave->binlog_pos += (extract_field(ptr+4, 32) << 32);
|
||||
slave->binlog_pos += (((uint64_t)extract_field(ptr+4, 32)) << 32);
|
||||
memcpy(slave->binlogfile, ptr + 8, len);
|
||||
slave->binlogfile[len] = 0;
|
||||
}
|
||||
@ -2006,6 +2014,9 @@ uint32_t chksum;
|
||||
|
||||
binlognamelen = strlen(slave->binlogfile);
|
||||
len = 19 + 8 + 4 + binlognamelen;
|
||||
/* no slave crc, remove 4 bytes */
|
||||
if (slave->nocrc)
|
||||
len -= 4;
|
||||
|
||||
/* no slave crc, remove 4 bytes */
|
||||
if (slave->nocrc)
|
||||
@ -2339,7 +2350,6 @@ blr_slave_disconnect_all(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave)
|
||||
uint8_t *ptr;
|
||||
int len, seqno;
|
||||
GWBUF *pkt;
|
||||
int n = 1;
|
||||
|
||||
/* preparing output result */
|
||||
blr_slave_send_fieldcount(router, slave, 2);
|
||||
@ -2389,7 +2399,7 @@ blr_slave_disconnect_all(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave)
|
||||
strncpy((char *)ptr, state, strlen(state)); // Result string
|
||||
ptr += strlen(state);
|
||||
|
||||
n = slave->dcb->func.write(slave->dcb, pkt);
|
||||
slave->dcb->func.write(slave->dcb, pkt);
|
||||
|
||||
/* force session close*/
|
||||
router_obj->closeSession(router->service->router_instance, sptr);
|
||||
|
||||
Reference in New Issue
Block a user