diff --git a/server/modules/routing/binlogrouter/blr.c b/server/modules/routing/binlogrouter/blr.c index 5b575c4f2..6bacd26e8 100644 --- a/server/modules/routing/binlogrouter/blr.c +++ b/server/modules/routing/binlogrouter/blr.c @@ -649,6 +649,8 @@ createInstance(SERVICE *service, char **options) MXS_ERROR("%s: Error: No router options supplied for binlogrouter", service->name); } + inst->orig_masterid = 0; + if (inst->masterid) { inst->set_master_server_id = true; @@ -3126,7 +3128,7 @@ static bool blr_open_gtid_maps_storage(ROUTER_INSTANCE *inst) "start_pos BIGINT, " "end_pos BIGINT);" "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;", NULL, NULL, &errmsg); if (rc != SQLITE_OK) diff --git a/server/modules/routing/binlogrouter/blr.h b/server/modules/routing/binlogrouter/blr.h index 75688af42..b8db2a419 100644 --- a/server/modules/routing/binlogrouter/blr.h +++ b/server/modules/routing/binlogrouter/blr.h @@ -98,6 +98,12 @@ MXS_BEGIN_DECLS /* GTID slite3 database name */ #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 * @@ -585,6 +591,7 @@ typedef struct router_instance ROUTER_SLAVE *slaves; /*< Link list of all the slave connections */ SPINLOCK lock; /*< Spinlock for the instance data */ 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 serverid; /*< ID for the router to use w/master */ int initbinlog; /*< Initial binlog file number */ diff --git a/server/modules/routing/binlogrouter/blr_file.c b/server/modules/routing/binlogrouter/blr_file.c index fc05d1242..9cd1a01ed 100644 --- a/server/modules/routing/binlogrouter/blr_file.c +++ b/server/modules/routing/binlogrouter/blr_file.c @@ -428,6 +428,30 @@ blr_file_create(ROUTER_INSTANCE *router, char *file) spinlock_release(&router->binlog_lock); 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, + >id_elms, + sizeof(MARIADB_GTID_ELEMS)); + + /* Save GTID into repo */ + blr_save_mariadb_gtid(router); + } } else { diff --git a/server/modules/routing/binlogrouter/blr_master.c b/server/modules/routing/binlogrouter/blr_master.c index 5fc1cc0b1..12b97d351 100644 --- a/server/modules/routing/binlogrouter/blr_master.c +++ b/server/modules/routing/binlogrouter/blr_master.c @@ -1103,6 +1103,7 @@ blr_handle_binlog_record(ROUTER_INSTANCE *router, GWBUF *pkt) strcpy(router->pending_transaction.gtid, mariadb_gtid); /* Save the pending GTID components */ 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.seq_no = n_sequence; } @@ -2274,6 +2275,12 @@ static void blr_register_heartbeat(ROUTER_INSTANCE *router, GWBUF *buf) "serverid", buf); + /** + * Keep the original master server id + * for any further reference. + */ + router->orig_masterid = atoi(val); + /** * Set router->masterid from master server-id * if it's not set by the config option diff --git a/server/modules/routing/binlogrouter/blr_slave.c b/server/modules/routing/binlogrouter/blr_slave.c index 5eae49ce1..8269bdb2c 100644 --- a/server/modules/routing/binlogrouter/blr_slave.c +++ b/server/modules/routing/binlogrouter/blr_slave.c @@ -100,9 +100,11 @@ */ typedef struct { - int seq_no; /* Output sequence in result test */ - char *last_file; /* Last binlog file found in GTID repository */ - DCB *client; /* Connected client DCB */ + int seq_no; /* Output sequence in result test */ + 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 */ } BINARY_LOG_DATA_RESULT; extern void poll_fake_write_event(DCB *dcb); @@ -313,7 +315,8 @@ static inline void blr_get_file_fullpath(const char *binlog_file, const char *root_dir, char *full_path); 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); 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 WARNINGS * SHOW [GLOBAL] STATUS LIKE 'Uptime' - * SHOW BINARY LOGS + * SHOW [FULL] BINARY LOGS * * 12 set commands are supported: * 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); 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) { - blr_show_binary_logs(router, slave); + blr_show_binary_logs(router, slave, word); } else { - char *errmsg = "SHOW BINARY LOGS needs the" + char *errmsg = "SHOW [FULL] BINARY LOGS needs the" " 'mariadb10_slave_gtid' option to be set."; MXS_ERROR("%s: %s", errmsg, @@ -7664,18 +7669,20 @@ static inline void blr_get_file_fullpath(const char *binlog_file, /** * Returns the list of binlog files + * saved in GTID repo. * * 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 slave The connected client - * @retun Sent bytes + * @param router The router instance + * @param slave The connected client + * @param extra_data Whether to dispay path file + * info before filename + * @retun Sent bytes */ 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]; uint64_t current_pos = 0; @@ -7689,6 +7696,7 @@ blr_show_binary_logs(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave) int seqno; char *errmsg = NULL; BINARY_LOG_DATA_RESULT result = {}; + bool extra_info = !strcasecmp(extra_data, "FULL"); /* Get current binlog finename and position */ spinlock_acquire(&router->binlog_lock); @@ -7730,6 +7738,8 @@ blr_show_binary_logs(ROUTER_INSTANCE *router, ROUTER_SLAVE *slave) result.seq_no = seqno; result.client = slave->dcb; result.last_file = NULL; + result.binlogdir = router->binlogdir; + result.extra_info = extra_info; /** * 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; DCB *dcb = data_set->client; int ret = 1; // Failure + uint32_t fsize; + char file_size[40]; ss_dassert(cols >= 4 && dcb); @@ -7855,13 +7867,52 @@ static int binary_logs_select_cb(void *data, values[3]) // Server ID { 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 */ - 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 */ - if ((pkt = blr_create_result_row(values[0], // File name - values[1], // File size + if ((pkt = blr_create_result_row(filename, // File name + file_size, // File size data_set->seq_no)) != NULL) { /* Increase sequence for next row */ @@ -7965,7 +8016,7 @@ static bool blr_handle_complex_select(ROUTER_INSTANCE *router, (strcasecmp(coln, "@@read_only") == 0 || strcasecmp(coln, "@@global.read_only") == 0)) { - blr_slave_send_id_ro(router, slave); + blr_slave_send_id_ro(router, slave); return true; } else