summaryrefslogtreecommitdiff
path: root/sql/repl_failsafe.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/repl_failsafe.cc')
-rw-r--r--sql/repl_failsafe.cc370
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.