MXS-1266: files are saved in GTID repo at creation time

Files are saved in GTID repo at creation time: this allows to show
files without transactions via SHOW [FULL] BINARY LOGS

The FULL keywords add domain_id and server id to the output as file
prefix: 0/10122/mysql-bin.000080
This commit is contained in:
MassimilianoPinto
2017-05-29 10:58:02 +02:00
parent a6e4ff1c10
commit f66623c382
5 changed files with 111 additions and 20 deletions

View File

@ -649,6 +649,8 @@ createInstance(SERVICE *service, char **options)
MXS_ERROR("%s: Error: No router options supplied for binlogrouter", service->name); MXS_ERROR("%s: Error: No router options supplied for binlogrouter", service->name);
} }
inst->orig_masterid = 0;
if (inst->masterid) if (inst->masterid)
{ {
inst->set_master_server_id = true; inst->set_master_server_id = true;
@ -3126,7 +3128,7 @@ static bool blr_open_gtid_maps_storage(ROUTER_INSTANCE *inst)
"start_pos BIGINT, " "start_pos BIGINT, "
"end_pos BIGINT);" "end_pos BIGINT);"
"CREATE UNIQUE INDEX IF NOT EXISTS gtid_index " "CREATE UNIQUE INDEX IF NOT EXISTS gtid_index "
"ON gtid_maps(rep_domain, server_id, sequence);" "ON gtid_maps(rep_domain, server_id, sequence, binlog_file);"
"COMMIT;", "COMMIT;",
NULL, NULL, &errmsg); NULL, NULL, &errmsg);
if (rc != SQLITE_OK) if (rc != SQLITE_OK)

View File

@ -98,6 +98,12 @@ MXS_BEGIN_DECLS
/* GTID slite3 database name */ /* GTID slite3 database name */
#define GTID_MAPS_DB "gtid_maps.db" #define GTID_MAPS_DB "gtid_maps.db"
/**
* Add GTID components domain and serverid as name prefix
* in SHOW FULL BINARY LOGS
*/
#define BINLOG_FILE_EXTRA_INFO GTID_MAX_LEN
/** /**
* Supported Encryption algorithms * Supported Encryption algorithms
* *
@ -585,6 +591,7 @@ typedef struct router_instance
ROUTER_SLAVE *slaves; /*< Link list of all the slave connections */ ROUTER_SLAVE *slaves; /*< Link list of all the slave connections */
SPINLOCK lock; /*< Spinlock for the instance data */ SPINLOCK lock; /*< Spinlock for the instance data */
char *uuid; /*< UUID for the router to use w/master */ char *uuid; /*< UUID for the router to use w/master */
int orig_masterid; /*< Server ID of the master, internally used */
int masterid; /*< Set ID of the master, sent to slaves */ int masterid; /*< Set ID of the master, sent to slaves */
int serverid; /*< ID for the router to use w/master */ int serverid; /*< ID for the router to use w/master */
int initbinlog; /*< Initial binlog file number */ int initbinlog; /*< Initial binlog file number */

View File

@ -428,6 +428,30 @@ blr_file_create(ROUTER_INSTANCE *router, char *file)
spinlock_release(&router->binlog_lock); spinlock_release(&router->binlog_lock);
created = 1; created = 1;
/**
* Add an entry in GTID repo with size 4
* and router->orig_masterid.
* This allows SHOW BINARY LOGS to list
* new created files.
*/
if (router->mariadb10_compat &&
router->mariadb10_gtid)
{
MARIADB_GTID_ELEMS gtid_elms = {};
// Add GTID domain
gtid_elms.domain_id = router->mariadb10_gtid_domain;
// router->orig_masterid keeps the original ID
gtid_elms.server_id = router->orig_masterid;
// Pos 4 only for end_pos
router->pending_transaction.end_pos = 4;
memcpy(&router->pending_transaction.gtid_elms,
&gtid_elms,
sizeof(MARIADB_GTID_ELEMS));
/* Save GTID into repo */
blr_save_mariadb_gtid(router);
}
} }
else else
{ {

View File

@ -1103,6 +1103,7 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt)
strcpy(router->pending_transaction.gtid, mariadb_gtid); strcpy(router->pending_transaction.gtid, mariadb_gtid);
/* Save the pending GTID components */ /* Save the pending GTID components */
router->pending_transaction.gtid_elms.domain_id = domainid; router->pending_transaction.gtid_elms.domain_id = domainid;
/* This is the master id, no override */
router->pending_transaction.gtid_elms.server_id = hdr.serverid; router->pending_transaction.gtid_elms.server_id = hdr.serverid;
router->pending_transaction.gtid_elms.seq_no = n_sequence; router->pending_transaction.gtid_elms.seq_no = n_sequence;
} }
@ -2274,6 +2275,12 @@ static void blr_register_heartbeat(ROUTER_INSTANCE *router, GWBUF *buf)
"serverid", "serverid",
buf); buf);
/**
* Keep the original master server id
* for any further reference.
*/
router->orig_masterid = atoi(val);
/** /**
* Set router->masterid from master server-id * Set router->masterid from master server-id
* if it's not set by the config option * if it's not set by the config option

View File

@ -101,7 +101,9 @@
typedef struct typedef struct
{ {
int seq_no; /* Output sequence in result test */ int seq_no; /* Output sequence in result test */
char *last_file; /* Last binlog file found in GTID repository */ char *last_file; /* Last binlog file found in GTID repo */
const char *binlogdir; /* Binlog files cache dir */
bool extra_info; /* Add extra ouput info */
DCB *client; /* Connected client DCB */ DCB *client; /* Connected client DCB */
} BINARY_LOG_DATA_RESULT; } BINARY_LOG_DATA_RESULT;
@ -313,7 +315,8 @@ static inline void blr_get_file_fullpath(const char *binlog_file,
const char *root_dir, const char *root_dir,
char *full_path); char *full_path);
static int blr_show_binary_logs(ROUTER_INSTANCE *router, static int blr_show_binary_logs(ROUTER_INSTANCE *router,
ROUTER_SLAVE *slave); ROUTER_SLAVE *slave,
const char *extra_data);
extern bool blr_parse_gtid(const char *gtid, MARIADB_GTID_ELEMS *info); extern bool blr_parse_gtid(const char *gtid, MARIADB_GTID_ELEMS *info);
static int binary_logs_select_cb(void *data, static int binary_logs_select_cb(void *data,
@ -555,7 +558,7 @@ blr_skip_leading_sql_comments(const char *sql_query)
* SHOW SLAVE HOSTS * SHOW SLAVE HOSTS
* SHOW WARNINGS * SHOW WARNINGS
* SHOW [GLOBAL] STATUS LIKE 'Uptime' * SHOW [GLOBAL] STATUS LIKE 'Uptime'
* SHOW BINARY LOGS * SHOW [FULL] BINARY LOGS
* *
* 12 set commands are supported: * 12 set commands are supported:
* SET @master_binlog_checksum = @@global.binlog_checksum * SET @master_binlog_checksum = @@global.binlog_checksum
@ -6754,15 +6757,17 @@ static bool blr_handle_show_stmt(ROUTER_INSTANCE *router,
blr_slave_show_warnings(router, slave); blr_slave_show_warnings(router, slave);
return true; return true;
} }
else if (strcasecmp(word, "BINARY") == 0) else if (strcasecmp(word, "BINARY") == 0 ||
(strcasecmp(word, "FULL") == 0 &&
strcasecmp(word, "BINARY")))
{ {
if (router->mariadb10_gtid) if (router->mariadb10_gtid)
{ {
blr_show_binary_logs(router, slave); blr_show_binary_logs(router, slave, word);
} }
else else
{ {
char *errmsg = "SHOW BINARY LOGS needs the" char *errmsg = "SHOW [FULL] BINARY LOGS needs the"
" 'mariadb10_slave_gtid' option to be set."; " 'mariadb10_slave_gtid' option to be set.";
MXS_ERROR("%s: %s", MXS_ERROR("%s: %s",
errmsg, errmsg,
@ -7664,18 +7669,20 @@ static inline void blr_get_file_fullpath(const char *binlog_file,
/** /**
* Returns the list of binlog files * Returns the list of binlog files
* saved in GTID repo.
* *
* It's called olny if mariadb10_slave_gtid option is set * It's called olny if mariadb10_slave_gtid option is set
* *
* Limitation: it doesn't return the current binlog file
* unless a GTID is found in it.
*
* @param router The router instance * @param router The router instance
* @param slave The connected client * @param slave The connected client
* @param extra_data Whether to dispay path file
* info before filename
* @retun Sent bytes * @retun Sent bytes
*/ */
static int static int
blr_show_binary_logs(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave) blr_show_binary_logs(ROUTER_INSTANCE *router,
ROUTER_SLAVE *slave,
const char *extra_data)
{ {
char current_file[BINLOG_FNAMELEN]; char current_file[BINLOG_FNAMELEN];
uint64_t current_pos = 0; uint64_t current_pos = 0;
@ -7689,6 +7696,7 @@ blr_show_binary_logs(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave)
int seqno; int seqno;
char *errmsg = NULL; char *errmsg = NULL;
BINARY_LOG_DATA_RESULT result = {}; BINARY_LOG_DATA_RESULT result = {};
bool extra_info = !strcasecmp(extra_data, "FULL");
/* Get current binlog finename and position */ /* Get current binlog finename and position */
spinlock_acquire(&router->binlog_lock); spinlock_acquire(&router->binlog_lock);
@ -7730,6 +7738,8 @@ blr_show_binary_logs(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave)
result.seq_no = seqno; result.seq_no = seqno;
result.client = slave->dcb; result.client = slave->dcb;
result.last_file = NULL; result.last_file = NULL;
result.binlogdir = router->binlogdir;
result.extra_info = extra_info;
/** /**
* Second part of result set: * Second part of result set:
@ -7846,6 +7856,8 @@ static int binary_logs_select_cb(void *data,
BINARY_LOG_DATA_RESULT *data_set = (BINARY_LOG_DATA_RESULT *)data; BINARY_LOG_DATA_RESULT *data_set = (BINARY_LOG_DATA_RESULT *)data;
DCB *dcb = data_set->client; DCB *dcb = data_set->client;
int ret = 1; // Failure int ret = 1; // Failure
uint32_t fsize;
char file_size[40];
ss_dassert(cols >= 4 && dcb); ss_dassert(cols >= 4 && dcb);
@ -7855,13 +7867,52 @@ static int binary_logs_select_cb(void *data,
values[3]) // Server ID values[3]) // Server ID
{ {
GWBUF *pkt; GWBUF *pkt;
char file_path[PATH_MAX + 1];
char filename[1 +
strlen(values[0]) +
BINLOG_FILE_EXTRA_INFO];
fsize = atoll(values[1]);
/* File size != 0 && server ID != 0 */ /* File size != 0 && server ID != 0 */
ss_dassert(atoll(values[1]) && atoll(values[3])); ss_dassert(fsize && atoll(values[3]));
/**
* In GTID repo binlog file last pos is last GTID.
* In case of rotate_event or any event the "file_size"
* it's not correct.
* In case of binlog files with no transactions at all
* the saved size is 4.
*
* Let's get the real size by calling blr_slave_get_file_size()
*/
//Get binlog filename full-path
blr_get_file_fullpath(values[0],
data_set->binlogdir,
file_path);
//Get the file size
fsize = blr_slave_get_file_size(file_path);
sprintf(file_size, "%" PRIu32 "", fsize);
// Include extra output
if (data_set->extra_info)
{
sprintf(filename,
"%s/%s/%s",
values[2], // domain ID
values[3], // server ID
values[0]); // filename
}
else
{
sprintf(filename, "%s", values[0]); // filename only
}
/* Create the MySQL Result Set row */ /* Create the MySQL Result Set row */
if ((pkt = blr_create_result_row(values[0], // File name if ((pkt = blr_create_result_row(filename, // File name
values[1], // File size file_size, // File size
data_set->seq_no)) != NULL) data_set->seq_no)) != NULL)
{ {
/* Increase sequence for next row */ /* Increase sequence for next row */