MXS-1209: added SELECT @@GLOBAL.gtid_domain_id for Master GTID registration
Master GTID registration: added first step: support for “SELECT @@GLOBAL.gtid_domain_id”
This commit is contained in:
@ -373,9 +373,6 @@ createInstance(SERVICE *service, char **options)
|
|||||||
/* Encryption CTX */
|
/* Encryption CTX */
|
||||||
inst->encryption_ctx = NULL;
|
inst->encryption_ctx = NULL;
|
||||||
|
|
||||||
/* MariaDB GTID repo init val */
|
|
||||||
inst->gtid_repo = NULL;
|
|
||||||
|
|
||||||
/* Set router uuid */
|
/* Set router uuid */
|
||||||
inst->uuid = config_copy_string(params, "uuid");
|
inst->uuid = config_copy_string(params, "uuid");
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ typedef struct router_instance
|
|||||||
bool mariadb_gtid; /*< Save received MariaDB GTIDs into repo.
|
bool mariadb_gtid; /*< Save received MariaDB GTIDs into repo.
|
||||||
* This allows MariaDB 10 slave servers
|
* This allows MariaDB 10 slave servers
|
||||||
* connecting with GTID */
|
* connecting with GTID */
|
||||||
HASHTABLE *gtid_repo; /*< Storage for MariaDB GTIDs */
|
uint32_t mariadb_gtid_domain; /*< MariaDB 10 GTID Domain ID */
|
||||||
sqlite3 *gtid_maps; /*< GTID storage */
|
sqlite3 *gtid_maps; /*< GTID storage */
|
||||||
struct router_instance *next;
|
struct router_instance *next;
|
||||||
} ROUTER_INSTANCE;
|
} ROUTER_INSTANCE;
|
||||||
@ -737,30 +737,34 @@ typedef struct binlog_pos_fix
|
|||||||
#define BLRM_CHKSUM1 0x0007
|
#define BLRM_CHKSUM1 0x0007
|
||||||
#define BLRM_CHKSUM2 0x0008
|
#define BLRM_CHKSUM2 0x0008
|
||||||
#define BLRM_MARIADB10 0x0009
|
#define BLRM_MARIADB10 0x0009
|
||||||
#define BLRM_GTIDMODE 0x000A
|
#define BLRM_MARIADB10_GTID_DOMAIN 0x000A
|
||||||
#define BLRM_MUUID 0x000B
|
#define BLRM_MARIADB10_REQUEST_GTID 0x000B
|
||||||
#define BLRM_SUUID 0x000C
|
#define BLRM_MARIADB10_GTID_STRICT 0x000C
|
||||||
#define BLRM_LATIN1 0x000D
|
#define BLRM_MARIADB10_GTID_NO_DUP 0x000D
|
||||||
#define BLRM_UTF8 0x000E
|
#define BLRM_GTIDMODE 0x000E
|
||||||
#define BLRM_RESULTS_CHARSET 0x000F
|
#define BLRM_MUUID 0x000F
|
||||||
#define BLRM_SQL_MODE 0x0010
|
#define BLRM_SUUID 0x0010
|
||||||
#define BLRM_SELECT1 0x0011
|
#define BLRM_LATIN1 0x0011
|
||||||
#define BLRM_SELECTVER 0x0012
|
#define BLRM_UTF8 0x0012
|
||||||
#define BLRM_SELECTVERCOM 0x0013
|
#define BLRM_RESULTS_CHARSET 0x0013
|
||||||
#define BLRM_SELECTHOSTNAME 0x0014
|
#define BLRM_SQL_MODE 0x0014
|
||||||
#define BLRM_MAP 0x0015
|
#define BLRM_SELECT1 0x0015
|
||||||
#define BLRM_SERVER_VARS 0x0016
|
#define BLRM_SELECTVER 0x0016
|
||||||
#define BLRM_BINLOG_VARS 0x0017
|
#define BLRM_SELECTVERCOM 0x0017
|
||||||
#define BLRM_LOWER_CASE_TABLES 0x0018
|
#define BLRM_SELECTHOSTNAME 0x0018
|
||||||
#define BLRM_REGISTER_READY 0x0019
|
#define BLRM_MAP 0x0019
|
||||||
#define BLRM_REGISTER 0x001A
|
#define BLRM_SERVER_VARS 0x001A
|
||||||
#define BLRM_CHECK_SEMISYNC 0x001B
|
#define BLRM_BINLOG_VARS 0x001B
|
||||||
#define BLRM_REQUEST_SEMISYNC 0x001C
|
#define BLRM_LOWER_CASE_TABLES 0x001C
|
||||||
#define BLRM_REQUEST_BINLOGDUMP 0x001D
|
#define BLRM_REGISTER_READY 0x001D
|
||||||
#define BLRM_BINLOGDUMP 0x001E
|
#define BLRM_REGISTER 0x001E
|
||||||
#define BLRM_SLAVE_STOPPED 0x001F
|
#define BLRM_CHECK_SEMISYNC 0x001F
|
||||||
|
#define BLRM_REQUEST_SEMISYNC 0x0020
|
||||||
|
#define BLRM_REQUEST_BINLOGDUMP 0x0021
|
||||||
|
#define BLRM_BINLOGDUMP 0x0022
|
||||||
|
#define BLRM_SLAVE_STOPPED 0x0023
|
||||||
|
|
||||||
#define BLRM_MAXSTATE 0x001F
|
#define BLRM_MAXSTATE 0x0023
|
||||||
|
|
||||||
static char *blrm_states[] =
|
static char *blrm_states[] =
|
||||||
{
|
{
|
||||||
@ -773,7 +777,11 @@ static char *blrm_states[] =
|
|||||||
"HeartBeat Period setup",
|
"HeartBeat Period setup",
|
||||||
"binlog checksum config",
|
"binlog checksum config",
|
||||||
"binlog checksum rerieval",
|
"binlog checksum rerieval",
|
||||||
"Set MariaDB slave capability",
|
"Set MariaDB10 slave capability",
|
||||||
|
"MariaDB10 GTID Domain retrieval",
|
||||||
|
"Set MariaDB10 GTID Request",
|
||||||
|
"Set MariaDB10 GTID strict mode",
|
||||||
|
"Set MariaDB10 GTID ignore duplicates",
|
||||||
"GTID Mode retrieval",
|
"GTID Mode retrieval",
|
||||||
"Master UUID retrieval",
|
"Master UUID retrieval",
|
||||||
"Set Slave UUID",
|
"Set Slave UUID",
|
||||||
|
@ -57,7 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "blr.h"
|
#include "blr.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -71,20 +70,13 @@
|
|||||||
#include <maxscale/housekeeper.h>
|
#include <maxscale/housekeeper.h>
|
||||||
#include <maxscale/buffer.h>
|
#include <maxscale/buffer.h>
|
||||||
#include <maxscale/worker.h>
|
#include <maxscale/worker.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <maxscale/log_manager.h>
|
#include <maxscale/log_manager.h>
|
||||||
|
|
||||||
#include <maxscale/thread.h>
|
#include <maxscale/thread.h>
|
||||||
|
|
||||||
/* Temporary requirement for auth data */
|
|
||||||
#include <maxscale/protocol/mysql.h>
|
#include <maxscale/protocol/mysql.h>
|
||||||
#include <maxscale/alloc.h>
|
#include <maxscale/alloc.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GWBUF *blr_make_query(DCB *dcb, char *query);
|
static GWBUF *blr_make_query(DCB *dcb, char *query);
|
||||||
static GWBUF *blr_make_registration(ROUTER_INSTANCE *router);
|
static GWBUF *blr_make_registration(ROUTER_INSTANCE *router);
|
||||||
static GWBUF *blr_make_binlog_dump(ROUTER_INSTANCE *router);
|
static GWBUF *blr_make_binlog_dump(ROUTER_INSTANCE *router);
|
||||||
@ -97,17 +89,12 @@ static void blr_log_packet(int priority, char *msg, uint8_t *ptr, int len);
|
|||||||
void blr_master_close(ROUTER_INSTANCE *);
|
void blr_master_close(ROUTER_INSTANCE *);
|
||||||
char *blr_extract_column(GWBUF *buf, int col);
|
char *blr_extract_column(GWBUF *buf, int col);
|
||||||
void poll_fake_write_event(DCB *dcb);
|
void poll_fake_write_event(DCB *dcb);
|
||||||
GWBUF *blr_read_events_from_pos(ROUTER_INSTANCE *router,
|
|
||||||
unsigned long long pos,
|
|
||||||
REP_HEADER *hdr,
|
|
||||||
unsigned long long pos_end);
|
|
||||||
static void blr_check_last_master_event(void *inst);
|
static void blr_check_last_master_event(void *inst);
|
||||||
extern int blr_check_heartbeat(ROUTER_INSTANCE *router);
|
extern int blr_check_heartbeat(ROUTER_INSTANCE *router);
|
||||||
static void blr_log_identity(ROUTER_INSTANCE *router);
|
static void blr_log_identity(ROUTER_INSTANCE *router);
|
||||||
static void blr_extract_header_semisync(uint8_t *pkt, REP_HEADER *hdr);
|
static void blr_extract_header_semisync(uint8_t *pkt, REP_HEADER *hdr);
|
||||||
static int blr_send_semisync_ack (ROUTER_INSTANCE *router, uint64_t pos);
|
static int blr_send_semisync_ack (ROUTER_INSTANCE *router, uint64_t pos);
|
||||||
static int blr_get_master_semisync(GWBUF *buf);
|
static int blr_get_master_semisync(GWBUF *buf);
|
||||||
|
|
||||||
static void blr_terminate_master_replication(ROUTER_INSTANCE *router,
|
static void blr_terminate_master_replication(ROUTER_INSTANCE *router,
|
||||||
uint8_t* ptr,
|
uint8_t* ptr,
|
||||||
int len);
|
int len);
|
||||||
@ -140,6 +127,8 @@ static void blr_register_cache_response(ROUTER_INSTANCE *router,
|
|||||||
const char *save_tag,
|
const char *save_tag,
|
||||||
GWBUF *in_buf);
|
GWBUF *in_buf);
|
||||||
static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf);
|
static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf);
|
||||||
|
static void blr_register_mariadb_gtid_domain(ROUTER_INSTANCE *router,
|
||||||
|
GWBUF *buf);
|
||||||
|
|
||||||
static void worker_cb_start_master(int worker_id, void* data);
|
static void worker_cb_start_master(int worker_id, void* data);
|
||||||
static void blr_start_master_in_main(void* data);
|
static void blr_start_master_in_main(void* data);
|
||||||
@ -181,12 +170,14 @@ blr_start_master(void* data)
|
|||||||
if (router->master_state != BLRM_SLAVE_STOPPED)
|
if (router->master_state != BLRM_SLAVE_STOPPED)
|
||||||
{
|
{
|
||||||
MXS_ERROR("%s: Master Connect: Unexpected master state %s\n",
|
MXS_ERROR("%s: Master Connect: Unexpected master state %s\n",
|
||||||
router->service->name, blrm_states[router->master_state]);
|
router->service->name,
|
||||||
|
blrm_states[router->master_state]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXS_NOTICE("%s: Master Connect: binlog state is %s\n",
|
MXS_NOTICE("%s: Master Connect: binlog state is %s\n",
|
||||||
router->service->name, blrm_states[router->master_state]);
|
router->service->name,
|
||||||
|
blrm_states[router->master_state]);
|
||||||
}
|
}
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
return;
|
return;
|
||||||
@ -233,7 +224,9 @@ blr_start_master(void* data)
|
|||||||
if (name)
|
if (name)
|
||||||
{
|
{
|
||||||
sprintf(name, "%s Master", router->service->name);
|
sprintf(name, "%s Master", router->service->name);
|
||||||
hktask_oneshot(name, blr_start_master_in_main, router,
|
hktask_oneshot(name,
|
||||||
|
blr_start_master_in_main,
|
||||||
|
router,
|
||||||
BLR_MASTER_BACKOFF_TIME * router->retry_backoff++);
|
BLR_MASTER_BACKOFF_TIME * router->retry_backoff++);
|
||||||
MXS_FREE(name);
|
MXS_FREE(name);
|
||||||
}
|
}
|
||||||
@ -247,13 +240,21 @@ blr_start_master(void* data)
|
|||||||
}
|
}
|
||||||
router->master->remote = MXS_STRDUP_A(router->service->dbref->server->name);
|
router->master->remote = MXS_STRDUP_A(router->service->dbref->server->name);
|
||||||
|
|
||||||
MXS_NOTICE("%s: attempting to connect to master server [%s]:%d, binlog %s, pos %lu",
|
MXS_NOTICE("%s: attempting to connect to master"
|
||||||
router->service->name, router->service->dbref->server->name,
|
" server [%s]:%d, binlog %s, pos %lu",
|
||||||
router->service->dbref->server->port, router->binlog_name, router->current_pos);
|
router->service->name,
|
||||||
|
router->service->dbref->server->name,
|
||||||
|
router->service->dbref->server->port,
|
||||||
|
router->binlog_name,
|
||||||
|
router->current_pos);
|
||||||
|
|
||||||
router->connect_time = time(0);
|
router->connect_time = time(0);
|
||||||
|
|
||||||
if (setsockopt(router->master->fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive , sizeof(keepalive )))
|
if (setsockopt(router->master->fd,
|
||||||
|
SOL_SOCKET,
|
||||||
|
SO_KEEPALIVE,
|
||||||
|
&keepalive,
|
||||||
|
sizeof(keepalive)))
|
||||||
{
|
{
|
||||||
perror("setsockopt");
|
perror("setsockopt");
|
||||||
}
|
}
|
||||||
@ -444,14 +445,12 @@ blr_master_delayed_connect(ROUTER_INSTANCE *router)
|
|||||||
void
|
void
|
||||||
blr_master_response(ROUTER_INSTANCE *router, GWBUF *buf)
|
blr_master_response(ROUTER_INSTANCE *router, GWBUF *buf)
|
||||||
{
|
{
|
||||||
char query[BLRM_MASTER_REGITRATION_QUERY_LEN + 1];
|
|
||||||
char task_name[BLRM_TASK_NAME_LEN + 1] = "";
|
|
||||||
|
|
||||||
atomic_add(&router->handling_threads, 1);
|
atomic_add(&router->handling_threads, 1);
|
||||||
ss_dassert(router->handling_threads == 1);
|
ss_dassert(router->handling_threads == 1);
|
||||||
spinlock_acquire(&router->lock);
|
spinlock_acquire(&router->lock);
|
||||||
router->active_logs = 1;
|
router->active_logs = 1;
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
|
|
||||||
if (router->master_state > BLRM_MAXSTATE)
|
if (router->master_state > BLRM_MAXSTATE)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Invalid master state machine state (%d) for binlog router.",
|
MXS_ERROR("Invalid master state machine state (%d) for binlog router.",
|
||||||
@ -547,6 +546,7 @@ blr_master_response(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
{
|
{
|
||||||
blr_restart_master(router);
|
blr_restart_master(router);
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_acquire(&router->lock);
|
spinlock_acquire(&router->lock);
|
||||||
router->active_logs = 0;
|
router->active_logs = 0;
|
||||||
spinlock_release(&router->lock);
|
spinlock_release(&router->lock);
|
||||||
@ -1647,143 +1647,6 @@ blr_extract_column(GWBUF *buf, int col)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a replication event form current opened binlog into a GWBUF structure.
|
|
||||||
*
|
|
||||||
* @param router The router instance
|
|
||||||
* @param pos Position of binlog record to read
|
|
||||||
* @param hdr Binlog header to populate
|
|
||||||
* @return The binlog record wrapped in a GWBUF structure
|
|
||||||
*/
|
|
||||||
GWBUF
|
|
||||||
*blr_read_events_from_pos(ROUTER_INSTANCE *router,
|
|
||||||
unsigned long long pos,
|
|
||||||
REP_HEADER *hdr,
|
|
||||||
unsigned long long pos_end)
|
|
||||||
{
|
|
||||||
unsigned long long end_pos = 0;
|
|
||||||
uint8_t hdbuf[19];
|
|
||||||
uint8_t *data;
|
|
||||||
GWBUF *result;
|
|
||||||
int n;
|
|
||||||
int event_limit;
|
|
||||||
|
|
||||||
/* Get current binnlog position */
|
|
||||||
end_pos = pos_end;
|
|
||||||
|
|
||||||
/* end of file reached, we're done */
|
|
||||||
if (pos == end_pos)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* error */
|
|
||||||
if (pos > end_pos)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events, the specified pos %llu "
|
|
||||||
"is ahead of current pos %lu for file %s",
|
|
||||||
pos, router->current_pos, router->binlog_name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the event header information from the file */
|
|
||||||
if ((n = pread(router->binlog_fd, hdbuf, 19, pos)) != 19)
|
|
||||||
{
|
|
||||||
switch (n)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
MXS_DEBUG("Reading saved events: reached end of binlog file at %llu.", pos);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: failed to read binlog "
|
|
||||||
"file %s at position %llu"
|
|
||||||
" (%s).", router->binlog_name,
|
|
||||||
pos, mxs_strerror(errno));
|
|
||||||
|
|
||||||
if (errno == EBADF)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: bad file descriptor for file %s"
|
|
||||||
", descriptor %d.",
|
|
||||||
router->binlog_name, router->binlog_fd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MXS_ERROR("Reading saved events: short read when reading the header. "
|
|
||||||
"Expected 19 bytes but got %d bytes. "
|
|
||||||
"Binlog file is %s, position %llu",
|
|
||||||
n, router->binlog_name, pos);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdr->timestamp = EXTRACT32(hdbuf);
|
|
||||||
hdr->event_type = hdbuf[4];
|
|
||||||
hdr->serverid = EXTRACT32(&hdbuf[5]);
|
|
||||||
hdr->event_size = extract_field(&hdbuf[9], 32);
|
|
||||||
hdr->next_pos = EXTRACT32(&hdbuf[13]);
|
|
||||||
hdr->flags = EXTRACT16(&hdbuf[17]);
|
|
||||||
|
|
||||||
event_limit = router->mariadb10_compat ? MAX_EVENT_TYPE_MARIADB10 : MAX_EVENT_TYPE;
|
|
||||||
|
|
||||||
if (hdr->event_type > event_limit)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: invalid event type 0x%x. "
|
|
||||||
"Binlog file is %s, position %llu",
|
|
||||||
hdr->event_type,
|
|
||||||
router->binlog_name, pos);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result = gwbuf_alloc(hdr->event_size)) == NULL)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: failed to allocate memory for binlog entry, "
|
|
||||||
"size %d at %llu.",
|
|
||||||
hdr->event_size, pos);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy event header*/
|
|
||||||
data = GWBUF_DATA(result);
|
|
||||||
memcpy(data, hdbuf, 19);
|
|
||||||
|
|
||||||
/* Read event data and put int into buffer after header */
|
|
||||||
if ((n = pread(router->binlog_fd, &data[19], hdr->event_size - 19, pos + 19)) != hdr->event_size - 19)
|
|
||||||
{
|
|
||||||
if (n == -1)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: the event at %llu in %s. "
|
|
||||||
"%s, expected %d bytes.",
|
|
||||||
pos, router->binlog_name,
|
|
||||||
mxs_strerror(errno), hdr->event_size - 19);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: short read when reading "
|
|
||||||
"the event at %llu in %s. "
|
|
||||||
"Expected %d bytes got %d bytes.",
|
|
||||||
pos, router->binlog_name, hdr->event_size - 19, n);
|
|
||||||
|
|
||||||
if (end_pos - pos < hdr->event_size)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Reading saved events: binlog event "
|
|
||||||
"is close to the end of the binlog file, "
|
|
||||||
"current file size is %llu.", end_pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free buffer */
|
|
||||||
gwbuf_free(result);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop and start the master connection
|
* Stop and start the master connection
|
||||||
*
|
*
|
||||||
@ -1794,7 +1657,8 @@ blr_stop_start_master(ROUTER_INSTANCE *router)
|
|||||||
{
|
{
|
||||||
if (router->master)
|
if (router->master)
|
||||||
{
|
{
|
||||||
if (router->master->fd != -1 && router->master->state == DCB_STATE_POLLING)
|
if (router->master->fd != -1 &&
|
||||||
|
router->master->state == DCB_STATE_POLLING)
|
||||||
{
|
{
|
||||||
blr_master_close(router);
|
blr_master_close(router);
|
||||||
}
|
}
|
||||||
@ -1819,7 +1683,8 @@ blr_stop_start_master(ROUTER_INSTANCE *router)
|
|||||||
|
|
||||||
if (router->client)
|
if (router->client)
|
||||||
{
|
{
|
||||||
if (router->client->fd != -1 && router->client->state == DCB_STATE_POLLING)
|
if (router->client->fd != -1 &&
|
||||||
|
router->client->state == DCB_STATE_POLLING)
|
||||||
{
|
{
|
||||||
dcb_close(router->client);
|
dcb_close(router->client);
|
||||||
router->client = NULL;
|
router->client = NULL;
|
||||||
@ -1871,7 +1736,9 @@ blr_check_last_master_event(void *inst)
|
|||||||
* when master state is back to BLRM_BINLOGDUMP
|
* when master state is back to BLRM_BINLOGDUMP
|
||||||
* by blr_master_response()
|
* by blr_master_response()
|
||||||
*/
|
*/
|
||||||
snprintf(task_name, BLRM_TASK_NAME_LEN, "%s heartbeat", router->service->name);
|
snprintf(task_name, BLRM_TASK_NAME_LEN,
|
||||||
|
"%s heartbeat",
|
||||||
|
router->service->name);
|
||||||
|
|
||||||
hktask_remove(task_name);
|
hktask_remove(task_name);
|
||||||
}
|
}
|
||||||
@ -1900,7 +1767,8 @@ blr_check_heartbeat(ROUTER_INSTANCE *router)
|
|||||||
|
|
||||||
event_desc = blr_last_event_description(router);
|
event_desc = blr_last_event_description(router);
|
||||||
|
|
||||||
if (router->master_state == BLRM_BINLOGDUMP && router->lastEventReceived > 0)
|
if (router->master_state == BLRM_BINLOGDUMP &&
|
||||||
|
router->lastEventReceived > 0)
|
||||||
{
|
{
|
||||||
if ((t_now - router->stats.lastReply) > (router->heartbeat + BLR_NET_LATENCY_WAIT_TIME))
|
if ((t_now - router->stats.lastReply) > (router->heartbeat + BLR_NET_LATENCY_WAIT_TIME))
|
||||||
{
|
{
|
||||||
@ -1964,7 +1832,8 @@ static void blr_log_identity(ROUTER_INSTANCE *router)
|
|||||||
MXS_NOTICE("%s: identity seen by the master: "
|
MXS_NOTICE("%s: identity seen by the master: "
|
||||||
"server_id: %d, uuid: %s",
|
"server_id: %d, uuid: %s",
|
||||||
router->service->name,
|
router->service->name,
|
||||||
router->serverid, (router->uuid == NULL ? "not available" : router->uuid));
|
router->serverid,
|
||||||
|
(router->uuid == NULL ? "not available" : router->uuid));
|
||||||
|
|
||||||
/* Seen by the slaves */
|
/* Seen by the slaves */
|
||||||
|
|
||||||
@ -1974,7 +1843,8 @@ static void blr_log_identity(ROUTER_INSTANCE *router)
|
|||||||
MXS_NOTICE("%s: identity seen by the slaves: "
|
MXS_NOTICE("%s: identity seen by the slaves: "
|
||||||
"server_id: %d, hostname: %s, MySQL version: %s",
|
"server_id: %d, hostname: %s, MySQL version: %s",
|
||||||
router->service->name,
|
router->service->name,
|
||||||
router->masterid, (master_hostname == NULL ? "not available" : master_hostname),
|
router->masterid,
|
||||||
|
(master_hostname == NULL ? "not available" : master_hostname),
|
||||||
(master_version == NULL ? "not available" : master_version));
|
(master_version == NULL ? "not available" : master_version));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2181,7 +2051,9 @@ bool blr_send_event(blr_thread_role_t role,
|
|||||||
* @param ptr Pointer to the start of the packet
|
* @param ptr Pointer to the start of the packet
|
||||||
* @param len Length of the packet
|
* @param len Length of the packet
|
||||||
*/
|
*/
|
||||||
static void blr_terminate_master_replication(ROUTER_INSTANCE* router, uint8_t* ptr, int len)
|
static void blr_terminate_master_replication(ROUTER_INSTANCE* router,
|
||||||
|
uint8_t* ptr,
|
||||||
|
int len)
|
||||||
{
|
{
|
||||||
unsigned long mysql_errno = extract_field(ptr + 5, 16);
|
unsigned long mysql_errno = extract_field(ptr + 5, 16);
|
||||||
int msg_len = len - 7 - 6; // msg len is decreased by 7 and 6
|
int msg_len = len - 7 - 6; // msg len is decreased by 7 and 6
|
||||||
@ -2208,7 +2080,8 @@ static void blr_terminate_master_replication(ROUTER_INSTANCE* router, uint8_t* p
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate a header structure for a replication message from a GWBUF structure with semi-sync enabled.
|
* Populate a header structure for a replication messager
|
||||||
|
* from a GWBUF structure with semi-sync enabled.
|
||||||
*
|
*
|
||||||
* @param pkt The incoming packet in a GWBUF chain
|
* @param pkt The incoming packet in a GWBUF chain
|
||||||
* @param hdr The packet header to populate
|
* @param hdr The packet header to populate
|
||||||
@ -2296,7 +2169,7 @@ blr_get_master_semisync(GWBUF *buf)
|
|||||||
{
|
{
|
||||||
val = blr_extract_column(buf, 2);
|
val = blr_extract_column(buf, 2);
|
||||||
}
|
}
|
||||||
free(key);
|
MXS_FREE(key);
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
@ -2309,7 +2182,7 @@ blr_get_master_semisync(GWBUF *buf)
|
|||||||
master_semisync = MASTER_SEMISYNC_DISABLED;
|
master_semisync = MASTER_SEMISYNC_DISABLED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(val);
|
MXS_FREE(val);
|
||||||
|
|
||||||
return master_semisync;
|
return master_semisync;
|
||||||
}
|
}
|
||||||
@ -2899,24 +2772,34 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
blr_register_send_command(router, command, state);
|
blr_register_send_command(router, command, state);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BLRM_MARIADB10:
|
case BLRM_MARIADB10: // MariaDB10 Only
|
||||||
// Save server response
|
// Save server response
|
||||||
blr_register_cache_response(router,
|
blr_register_cache_response(router,
|
||||||
&router->saved_master.mariadb10,
|
&router->saved_master.mariadb10,
|
||||||
"mariadb10",
|
"mariadb10",
|
||||||
buf);
|
buf);
|
||||||
// Skip SERVER_UUID fetch and SET slave UUID
|
// Next state is BLRM_MARIADB10_GTID_DOMAIN or BLRM_LATIN1
|
||||||
blr_register_send_command(router,
|
{
|
||||||
"SET NAMES latin1",
|
unsigned int state = router->mariadb_gtid ?
|
||||||
BLRM_LATIN1);
|
BLRM_MARIADB10_GTID_DOMAIN :
|
||||||
|
BLRM_LATIN1;
|
||||||
|
const char *command = router->mariadb_gtid ?
|
||||||
|
"SELECT @@GLOBAL.gtid_domain_id" :
|
||||||
|
"SET NAMES latin1";
|
||||||
|
blr_register_send_command(router, command, state);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BLRM_GTIDMODE: // MySQL 5.6/7 only
|
case BLRM_MARIADB10_GTID_DOMAIN: // MariaDB10 Only
|
||||||
|
// Next state is BLRM_LATIN1
|
||||||
|
blr_register_mariadb_gtid_domain(router, buf);
|
||||||
|
break;
|
||||||
|
case BLRM_GTIDMODE: // MySQL 5.6/5.7 only
|
||||||
blr_register_serveruuid(router, buf);
|
blr_register_serveruuid(router, buf);
|
||||||
break;
|
break;
|
||||||
case BLRM_MUUID: // MySQL 5.6/7 only
|
case BLRM_MUUID: // MySQL 5.6/5.7 only
|
||||||
blr_register_slaveuuid(router, buf);
|
blr_register_slaveuuid(router, buf);
|
||||||
break;
|
break;
|
||||||
case BLRM_SUUID: // MySQL 5.6/7 only
|
case BLRM_SUUID: // MySQL 5.6/5.7 only
|
||||||
// Save server response
|
// Save server response
|
||||||
blr_register_cache_response(router,
|
blr_register_cache_response(router,
|
||||||
&router->saved_master.setslaveuuid,
|
&router->saved_master.setslaveuuid,
|
||||||
@ -2935,8 +2818,7 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
&router->saved_master.utf8,
|
&router->saved_master.utf8,
|
||||||
"utf8",
|
"utf8",
|
||||||
buf);
|
buf);
|
||||||
// Next state is MAXWELL BLRM_RESULTS_CHARSET or
|
// Next state is MAXWELL BLRM_RESULTS_CHARSET or BLRM_SELECT1
|
||||||
// BLRM_SELECT1
|
|
||||||
{
|
{
|
||||||
unsigned int state = router->maxwell_compat ?
|
unsigned int state = router->maxwell_compat ?
|
||||||
BLRM_RESULTS_CHARSET :
|
BLRM_RESULTS_CHARSET :
|
||||||
@ -2948,13 +2830,13 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
blr_register_send_command(router, command, state);
|
blr_register_send_command(router, command, state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BLRM_RESULTS_CHARSET:
|
case BLRM_RESULTS_CHARSET: // MAXWELL only
|
||||||
gwbuf_free(buf); // Discard server reply, don't save it
|
gwbuf_free(buf); // Discard server reply, don't save it
|
||||||
blr_register_send_command(router,
|
blr_register_send_command(router,
|
||||||
MYSQL_CONNECTOR_SQL_MODE_QUERY,
|
MYSQL_CONNECTOR_SQL_MODE_QUERY,
|
||||||
BLRM_SQL_MODE);
|
BLRM_SQL_MODE);
|
||||||
break;
|
break;
|
||||||
case BLRM_SQL_MODE:
|
case BLRM_SQL_MODE: // MAXWELL only
|
||||||
gwbuf_free(buf); // Discard server reply, don't save it
|
gwbuf_free(buf); // Discard server reply, don't save it
|
||||||
blr_register_send_command(router,
|
blr_register_send_command(router,
|
||||||
"SELECT 1",
|
"SELECT 1",
|
||||||
@ -2990,7 +2872,7 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
// Continue: ready for the registration, nothing to write/read
|
// Continue: ready for the registration, nothing to write/read
|
||||||
router->master_state = BLRM_REGISTER_READY;
|
router->master_state = BLRM_REGISTER_READY;
|
||||||
}
|
}
|
||||||
case BLRM_SERVER_VARS:
|
case BLRM_SERVER_VARS: // MAXWELL only
|
||||||
/**
|
/**
|
||||||
* This branch could be reached as fallthrough from BLRM_MAP
|
* This branch could be reached as fallthrough from BLRM_MAP
|
||||||
* with new state BLRM_REGISTER_READY
|
* with new state BLRM_REGISTER_READY
|
||||||
@ -3001,7 +2883,7 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
blr_register_mxw_binlogvars(router, buf);
|
blr_register_mxw_binlogvars(router, buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BLRM_BINLOG_VARS:
|
case BLRM_BINLOG_VARS: // MAXWELL only
|
||||||
/**
|
/**
|
||||||
* This branch could be reached as fallthrough from BLRM_MAP
|
* This branch could be reached as fallthrough from BLRM_MAP
|
||||||
* with new state BLRM_REGISTER_READY.
|
* with new state BLRM_REGISTER_READY.
|
||||||
@ -3012,7 +2894,7 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
blr_register_mxw_tables(router, buf);
|
blr_register_mxw_tables(router, buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BLRM_LOWER_CASE_TABLES:
|
case BLRM_LOWER_CASE_TABLES: // MAXWELL only
|
||||||
/**
|
/**
|
||||||
* This branch could be reached as fallthrough from BLRM_MAP
|
* This branch could be reached as fallthrough from BLRM_MAP
|
||||||
* with new state BLRM_REGISTER_READY.
|
* with new state BLRM_REGISTER_READY.
|
||||||
@ -3061,8 +2943,9 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
}
|
}
|
||||||
case BLRM_REQUEST_SEMISYNC:
|
case BLRM_REQUEST_SEMISYNC:
|
||||||
/**
|
/**
|
||||||
* This branch could be reached as fallthrough from BLRM_REGISTER or BLRM_CHECK_SEMISYNC
|
* This branch could be reached as fallthrough from BLRM_REGISTER or
|
||||||
* if request_semi_sync option is false or master doesn't support semisync or it's not enabled
|
* BLRM_CHECK_SEMISYNC if request_semi_sync option is false or
|
||||||
|
* master doesn't support semisync or it's not enabled.
|
||||||
*/
|
*/
|
||||||
if (router->master_state == BLRM_REQUEST_SEMISYNC)
|
if (router->master_state == BLRM_REQUEST_SEMISYNC)
|
||||||
{
|
{
|
||||||
@ -3075,10 +2958,15 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
case BLRM_REQUEST_BINLOGDUMP:
|
case BLRM_REQUEST_BINLOGDUMP:
|
||||||
/**
|
/**
|
||||||
* This branch is reached after semi-sync check/request or
|
* This branch is reached after semi-sync check/request or
|
||||||
* just after sending COM_REGISTER_SLAVE if request_semi_sync option is false
|
* just after sending COM_REGISTER_SLAVE
|
||||||
|
* if request_semi_sync option is false.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Request now a dump of the binlog file: COM_BINLOG_DUMP */
|
/**
|
||||||
|
* End of registration process:
|
||||||
|
*
|
||||||
|
* Now request a dump of the binlog file: COM_BINLOG_DUMP
|
||||||
|
*/
|
||||||
buf = blr_make_binlog_dump(router);
|
buf = blr_make_binlog_dump(router);
|
||||||
router->master_state = BLRM_BINLOGDUMP;
|
router->master_state = BLRM_BINLOGDUMP;
|
||||||
router->master->func.write(router->master, buf);
|
router->master->func.write(router->master, buf);
|
||||||
@ -3102,9 +2990,40 @@ static void blr_start_master_registration(ROUTER_INSTANCE *router, GWBUF *buf)
|
|||||||
/**
|
/**
|
||||||
* Set heartbeat check task
|
* Set heartbeat check task
|
||||||
*/
|
*/
|
||||||
snprintf(task_name, BLRM_TASK_NAME_LEN, "%s heartbeat", router->service->name);
|
snprintf(task_name,
|
||||||
hktask_add(task_name, blr_check_last_master_event, router, router->heartbeat);
|
BLRM_TASK_NAME_LEN,
|
||||||
|
"%s heartbeat",
|
||||||
|
router->service->name);
|
||||||
|
hktask_add(task_name,
|
||||||
|
blr_check_last_master_event,
|
||||||
|
router,
|
||||||
|
router->heartbeat);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slave Protocol registration to Master (MariaDB 10 compatibility):
|
||||||
|
*
|
||||||
|
* Handles previous reply from MariaDB10 Master (GTID Domain ID) and
|
||||||
|
* sets the state to BLRM_LATIN1
|
||||||
|
*
|
||||||
|
* @param router Current router instance
|
||||||
|
* @param buf GWBUF with server reply to previous
|
||||||
|
* registration command
|
||||||
|
*/
|
||||||
|
static void blr_register_mariadb_gtid_domain(ROUTER_INSTANCE *router,
|
||||||
|
GWBUF *buf)
|
||||||
|
{
|
||||||
|
// Extract GTID domain
|
||||||
|
char *val = blr_extract_column(buf, 1);
|
||||||
|
// Store the Master GTID domain
|
||||||
|
router->mariadb_gtid_domain = atol(val);
|
||||||
|
MXS_FREE(val);
|
||||||
|
// Don't save the server response
|
||||||
|
gwbuf_free(buf);
|
||||||
|
blr_register_send_command(router,
|
||||||
|
"SET NAMES latin1",
|
||||||
|
BLRM_LATIN1);
|
||||||
|
}
|
||||||
|
@ -6030,7 +6030,7 @@ static bool blr_handle_select_stmt(ROUTER_INSTANCE *router,
|
|||||||
slave,
|
slave,
|
||||||
heading,
|
heading,
|
||||||
mariadb_gtid,
|
mariadb_gtid,
|
||||||
BLR_TYPE_STRING);
|
BLR_TYPE_INT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (strcasecmp(word, "@@GLOBAL.gtid_domain_id") == 0)
|
else if (strcasecmp(word, "@@GLOBAL.gtid_domain_id") == 0)
|
||||||
@ -6039,13 +6039,17 @@ static bool blr_handle_select_stmt(ROUTER_INSTANCE *router,
|
|||||||
if (slave->mariadb10_compat && router->mariadb_gtid)
|
if (slave->mariadb10_compat && router->mariadb_gtid)
|
||||||
{
|
{
|
||||||
char heading[40];
|
char heading[40];
|
||||||
|
char gtid_domain[40];
|
||||||
|
sprintf(gtid_domain,
|
||||||
|
"%lu",
|
||||||
|
(unsigned long)router->mariadb_gtid_domain);
|
||||||
strcpy(heading, word);
|
strcpy(heading, word);
|
||||||
|
|
||||||
blr_slave_send_var_value(router,
|
blr_slave_send_var_value(router,
|
||||||
slave,
|
slave,
|
||||||
heading,
|
heading,
|
||||||
"0",
|
gtid_domain,
|
||||||
BLR_TYPE_STRING);
|
BLR_TYPE_INT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6532,7 +6536,11 @@ static bool blr_handle_maxwell_stmt(ROUTER_INSTANCE *router,
|
|||||||
{
|
{
|
||||||
char server_id[40];
|
char server_id[40];
|
||||||
sprintf(server_id, "%d", router->masterid);
|
sprintf(server_id, "%d", router->masterid);
|
||||||
blr_slave_send_var_value(router, slave, "server_id", server_id, BLR_TYPE_STRING);
|
blr_slave_send_var_value(router,
|
||||||
|
slave,
|
||||||
|
"server_id",
|
||||||
|
server_id,
|
||||||
|
BLR_TYPE_STRING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (strcmp(maxwell_stmt, maxwell_log_bin_query) == 0)
|
else if (strcmp(maxwell_stmt, maxwell_log_bin_query) == 0)
|
||||||
@ -6570,7 +6578,9 @@ static bool blr_handle_maxwell_stmt(ROUTER_INSTANCE *router,
|
|||||||
}
|
}
|
||||||
else if (strcmp(maxwell_stmt, maxwell_lower_case_tables_query) == 0)
|
else if (strcmp(maxwell_stmt, maxwell_lower_case_tables_query) == 0)
|
||||||
{
|
{
|
||||||
int rc = blr_slave_replay(router, slave, router->saved_master.lower_case_tables);
|
int rc = blr_slave_replay(router,
|
||||||
|
slave,
|
||||||
|
router->saved_master.lower_case_tables);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Error sending lower_case_tables query response");
|
MXS_ERROR("Error sending lower_case_tables query response");
|
||||||
|
Reference in New Issue
Block a user