diff options
Diffstat (limited to 'sql/repl_failsafe.cc')
-rw-r--r-- | sql/repl_failsafe.cc | 370 |
1 files changed, 2 insertions, 368 deletions
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 47eb2f7031d..bc710616a4c 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -41,7 +41,7 @@ #define SLAVE_ERRMSG_SIZE (FN_REFLEN+64) -RPL_STATUS rpl_status=RPL_NULL; +ulong rpl_status=RPL_NULL; mysql_mutex_t LOCK_rpl_status; mysql_cond_t COND_rpl_status; HASH slave_list; @@ -56,10 +56,6 @@ const char* rpl_status_type[]= "RECOVERY_CAPTAIN","NULL",NullS }; -static Slave_log_event* find_slave_event(IO_CACHE* log, - const char* log_file_name, - char* errmsg); - /* All of the functions defined in this file which are not used (the ones to handle failsafe) are not used; their code has not been updated for more than @@ -68,7 +64,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, functions like register_slave()) are working. */ -void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status) +void change_rpl_status(ulong from_status, ulong to_status) { mysql_mutex_lock(&LOCK_rpl_status); if (rpl_status == from_status || rpl_status == RPL_ANY) @@ -91,13 +87,6 @@ void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status) }\ -static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi) -{ - return cmp_master_pos(sev->master_log, sev->master_pos, mi->log_file_name, - mi->pos); -} - - void unregister_slave(THD* thd, bool only_mine, bool need_mutex) { if (thd->server_id) @@ -228,361 +217,6 @@ void end_slave_list() } } -static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg) -{ - my_off_t log_pos = (my_off_t) mi->pos; - uint32 target_server_id = mi->server_id; - - for (;;) - { - Log_event* ev; - if (!(ev= Log_event::read_log_event(log, (mysql_mutex_t*) 0, 0))) - { - if (log->error > 0) - strmov(errmsg, "Binary log truncated in the middle of event"); - else if (log->error < 0) - strmov(errmsg, "I/O error reading binary log"); - else - strmov(errmsg, "Could not find target event in the binary log"); - return 1; - } - - if (ev->log_pos >= log_pos && ev->server_id == target_server_id) - { - delete ev; - mi->pos = my_b_tell(log); - return 0; - } - delete ev; - } - /* Impossible */ -} - -/** - @details - Before 4.0.15 we had a member of THD called log_pos, it was meant for - failsafe replication code in repl_failsafe.cc which is disabled until - it is reworked. Event's log_pos used to be preserved through - log-slave-updates to make code in repl_failsafe.cc work (this - function, SHOW NEW MASTER); but on the other side it caused unexpected - values in Exec_Master_Log_Pos in A->B->C replication setup, - synchronization problems in master_pos_wait(), ... So we - (Dmitri & Guilhem) removed it. - - So for now this function is broken. -*/ - -int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) -{ - LOG_INFO linfo; - char last_log_name[FN_REFLEN]; - IO_CACHE log; - File file = -1, last_file = -1; - mysql_mutex_t *log_lock; - const char* errmsg_p; - Slave_log_event* sev = 0; - my_off_t last_pos = 0; - int error = 1; - int cmp_res; - LINT_INIT(cmp_res); - DBUG_ENTER("translate_master"); - - if (!mysql_bin_log.is_open()) - { - strmov(errmsg,"Binary log is not open"); - DBUG_RETURN(1); - } - - if (!server_id_supplied) - { - strmov(errmsg, "Misconfigured master - server id was not set"); - DBUG_RETURN(1); - } - - if (mysql_bin_log.find_log_pos(&linfo, NullS, 1)) - { - strmov(errmsg,"Could not find first log"); - DBUG_RETURN(1); - } - thd->current_linfo = &linfo; - - bzero((char*) &log,sizeof(log)); - log_lock = mysql_bin_log.get_log_lock(); - mysql_mutex_lock(log_lock); - - for (;;) - { - if ((file=open_binlog(&log, linfo.log_file_name, &errmsg_p)) < 0) - { - strmov(errmsg, errmsg_p); - goto err; - } - - if (!(sev = find_slave_event(&log, linfo.log_file_name, errmsg))) - goto err; - - cmp_res = cmp_master_pos(sev, mi); - delete sev; - - if (!cmp_res) - { - /* Copy basename */ - fn_format(mi->log_file_name, linfo.log_file_name, "","",1); - mi->pos = my_b_tell(&log); - goto mi_inited; - } - else if (cmp_res > 0) - { - if (!last_pos) - { - strmov(errmsg, - "Slave event in first log points past the target position"); - goto err; - } - end_io_cache(&log); - mysql_file_close(file, MYF(MY_WME)); - if (init_io_cache(&log, (file = last_file), IO_SIZE, READ_CACHE, 0, 0, - MYF(MY_WME))) - { - errmsg[0] = 0; - goto err; - } - break; - } - - strmov(last_log_name, linfo.log_file_name); - last_pos = my_b_tell(&log); - - switch (mysql_bin_log.find_next_log(&linfo, 1)) { - case LOG_INFO_EOF: - if (last_file >= 0) - mysql_file_close(last_file, MYF(MY_WME)); - last_file = -1; - goto found_log; - case 0: - break; - default: - strmov(errmsg, "Error reading log index"); - goto err; - } - - end_io_cache(&log); - if (last_file >= 0) - mysql_file_close(last_file, MYF(MY_WME)); - last_file = file; - } - -found_log: - my_b_seek(&log, last_pos); - if (find_target_pos(mi,&log,errmsg)) - goto err; - fn_format(mi->log_file_name, last_log_name, "","",1); /* Copy basename */ - -mi_inited: - error = 0; -err: - mysql_mutex_unlock(log_lock); - end_io_cache(&log); - mysql_mutex_lock(&LOCK_thread_count); - thd->current_linfo = 0; - mysql_mutex_unlock(&LOCK_thread_count); - if (file >= 0) - mysql_file_close(file, MYF(MY_WME)); - if (last_file >= 0 && last_file != file) - mysql_file_close(last_file, MYF(MY_WME)); - - DBUG_RETURN(error); -} - - -/** - Caller must delete result when done. -*/ - -static Slave_log_event* find_slave_event(IO_CACHE* log, - const char* log_file_name, - char* errmsg) -{ - Log_event* ev; - int i; - bool slave_event_found = 0; - LINT_INIT(ev); - - for (i = 0; i < 2; i++) - { - if (!(ev= Log_event::read_log_event(log, (mysql_mutex_t*)0, 0))) - { - my_snprintf(errmsg, SLAVE_ERRMSG_SIZE, - "Error reading event in log '%s'", - (char*)log_file_name); - return 0; - } - if (ev->get_type_code() == SLAVE_EVENT) - { - slave_event_found = 1; - break; - } - delete ev; - } - if (!slave_event_found) - { - my_snprintf(errmsg, SLAVE_ERRMSG_SIZE, - "Could not find slave event in log '%s'", - (char*)log_file_name); - return 0; - } - - return (Slave_log_event*)ev; -} - -/** - This function is broken now. - - @seealso translate_master() -*/ - -bool show_new_master(THD* thd) -{ - Protocol *protocol= thd->protocol; - DBUG_ENTER("show_new_master"); - List<Item> field_list; - char errmsg[SLAVE_ERRMSG_SIZE]; - LEX_MASTER_INFO* lex_mi= &thd->lex->mi; - - errmsg[0]=0; // Safety - if (translate_master(thd, lex_mi, errmsg)) - { - if (errmsg[0]) - my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), - "SHOW NEW MASTER", errmsg); - DBUG_RETURN(TRUE); - } - else - { - field_list.push_back(new Item_empty_string("Log_name", 20)); - field_list.push_back(new Item_return_int("Log_pos", 10, - MYSQL_TYPE_LONGLONG)); - if (protocol->send_result_set_metadata(&field_list, - Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) - DBUG_RETURN(TRUE); - protocol->prepare_for_resend(); - protocol->store(lex_mi->log_file_name, &my_charset_bin); - protocol->store((ulonglong) lex_mi->pos); - if (protocol->write()) - DBUG_RETURN(TRUE); - my_eof(thd); - DBUG_RETURN(FALSE); - } -} - -/** - Asks the master for the list of its other connected slaves. - - This is for failsafe replication: - in order for failsafe replication to work, the servers involved in - replication must know of each other. We accomplish this by having each - slave report to the master how to reach it, and on connection, each - slave receives information about where the other slaves are. - - @param mysql pre-existing connection to the master - @param mi master info - - @note - mi is used only to give detailed error messages which include the - hostname/port of the master, the username used by the slave to connect to - the master. - If the user used by the slave to connect to the master does not have the - REPLICATION SLAVE privilege, it will pop in this function because - SHOW SLAVE HOSTS will fail on the master. - - @retval - 1 error - @retval - 0 success -*/ - -int update_slave_list(MYSQL* mysql, Master_info* mi) -{ - MYSQL_RES* res=0; - MYSQL_ROW row; - const char* error=0; - bool have_auth_info; - int port_ind; - DBUG_ENTER("update_slave_list"); - - if (mysql_real_query(mysql, STRING_WITH_LEN("SHOW SLAVE HOSTS")) || - !(res = mysql_store_result(mysql))) - { - error= mysql_error(mysql); - goto err; - } - - switch (mysql_num_fields(res)) { - case 5: - have_auth_info = 0; - port_ind=2; - break; - case 7: - have_auth_info = 1; - port_ind=4; - break; - default: - error= "the master returned an invalid number of fields for SHOW SLAVE \ -HOSTS"; - goto err; - } - - mysql_mutex_lock(&LOCK_slave_list); - - while ((row= mysql_fetch_row(res))) - { - uint32 log_server_id; - SLAVE_INFO* si, *old_si; - log_server_id = atoi(row[0]); - if ((old_si= (SLAVE_INFO*)my_hash_search(&slave_list, - (uchar*)&log_server_id,4))) - si = old_si; - else - { - if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME)))) - { - error= "the slave is out of memory"; - mysql_mutex_unlock(&LOCK_slave_list); - goto err; - } - si->server_id = log_server_id; - if (my_hash_insert(&slave_list, (uchar*)si)) - { - error= "the slave is out of memory"; - mysql_mutex_unlock(&LOCK_slave_list); - goto err; - } - } - strmake(si->host, row[1], sizeof(si->host)-1); - si->port = atoi(row[port_ind]); - si->rpl_recovery_rank = atoi(row[port_ind+1]); - si->master_id = atoi(row[port_ind+2]); - if (have_auth_info) - { - strmake(si->user, row[2], sizeof(si->user)-1); - strmake(si->password, row[3], sizeof(si->password)-1); - } - } - mysql_mutex_unlock(&LOCK_slave_list); - -err: - if (res) - mysql_free_result(res); - if (error) - { - sql_print_error("While trying to obtain the list of slaves from the master " - "'%s:%d', user '%s' got the following error: '%s'", - mi->host, mi->port, mi->user, error); - DBUG_RETURN(1); - } - DBUG_RETURN(0); -} - /** Execute a SHOW SLAVE HOSTS statement. |