summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
authorunknown <lars@black.(none)>2006-11-13 12:45:31 +0100
committerunknown <lars@black.(none)>2006-11-13 12:45:31 +0100
commit36dfa434cc4f0aa31ef29f1a78f20c510bd93e9b (patch)
treeeb796a1a532ee9d10c8c44e5cd764977260d29a0 /sql/slave.cc
parentce963d0c8e3243b558ea54c11e8c5824b8dcf3b8 (diff)
parent421f4c090739cc993ce336048df7c0284896e886 (diff)
downloadmariadb-git-36dfa434cc4f0aa31ef29f1a78f20c510bd93e9b.tar.gz
Merge mysql.com:/home/bkroot/mysql-5.1-new-rpl
into mysql.com:/home/bk/MERGE/mysql-5.1-merge BitKeeper/etc/collapsed: auto-union mysql-test/r/view.result: Auto merged mysql-test/t/view.test: Auto merged sql/Makefile.am: Auto merged sql/handler.cc: Auto merged sql/log.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_view.cc: Auto merged
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc1493
1 files changed, 9 insertions, 1484 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index 00d6d168fb8..34d3cb64ba8 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -31,13 +31,15 @@
#include "rpl_tblmap.h"
+int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
+
+
#define MAX_SLAVE_RETRY_PAUSE 5
bool use_slave_mask = 0;
MY_BITMAP slave_error_mask;
typedef bool (*CHECK_KILLED_FUNC)(THD*,void*);
-volatile bool slave_sql_running = 0, slave_io_running = 0;
char* slave_load_tmpdir = 0;
MASTER_INFO *active_mi= 0;
my_bool replicate_same_server_id;
@@ -59,7 +61,6 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev);
static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli);
static inline bool io_slave_killed(THD* thd,MASTER_INFO* mi);
static inline bool sql_slave_killed(THD* thd,RELAY_LOG_INFO* rli);
-static int count_relay_log_space(RELAY_LOG_INFO* rli);
static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi);
static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
@@ -202,223 +203,6 @@ err:
/*
- Open the given relay log
-
- SYNOPSIS
- init_relay_log_pos()
- rli Relay information (will be initialized)
- log Name of relay log file to read from. NULL = First log
- pos Position in relay log file
- need_data_lock Set to 1 if this functions should do mutex locks
- errmsg Store pointer to error message here
- look_for_description_event
- 1 if we should look for such an event. We only need
- this when the SQL thread starts and opens an existing
- relay log and has to execute it (possibly from an
- offset >4); then we need to read the first event of
- the relay log to be able to parse the events we have
- to execute.
-
- DESCRIPTION
- - Close old open relay log files.
- - If we are using the same relay log as the running IO-thread, then set
- rli->cur_log to point to the same IO_CACHE entry.
- - If not, open the 'log' binary file.
-
- TODO
- - check proper initialization of group_master_log_name/group_master_log_pos
-
- RETURN VALUES
- 0 ok
- 1 error. errmsg is set to point to the error message
-*/
-
-int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
- ulonglong pos, bool need_data_lock,
- const char** errmsg,
- bool look_for_description_event)
-{
- DBUG_ENTER("init_relay_log_pos");
- DBUG_PRINT("info", ("pos=%lu", pos));
-
- *errmsg=0;
- pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
-
- if (need_data_lock)
- pthread_mutex_lock(&rli->data_lock);
-
- /*
- Slave threads are not the only users of init_relay_log_pos(). CHANGE MASTER
- is, too, and init_slave() too; these 2 functions allocate a description
- event in init_relay_log_pos, which is not freed by the terminating SQL slave
- thread as that thread is not started by these functions. So we have to free
- the description_event here, in case, so that there is no memory leak in
- running, say, CHANGE MASTER.
- */
- delete rli->relay_log.description_event_for_exec;
- /*
- By default the relay log is in binlog format 3 (4.0).
- Even if format is 4, this will work enough to read the first event
- (Format_desc) (remember that format 4 is just lenghtened compared to format
- 3; format 3 is a prefix of format 4).
- */
- rli->relay_log.description_event_for_exec= new
- Format_description_log_event(3);
-
- pthread_mutex_lock(log_lock);
-
- /* Close log file and free buffers if it's already open */
- if (rli->cur_log_fd >= 0)
- {
- end_io_cache(&rli->cache_buf);
- my_close(rli->cur_log_fd, MYF(MY_WME));
- rli->cur_log_fd = -1;
- }
-
- rli->group_relay_log_pos = rli->event_relay_log_pos = pos;
-
- /*
- Test to see if the previous run was with the skip of purging
- If yes, we do not purge when we restart
- */
- if (rli->relay_log.find_log_pos(&rli->linfo, NullS, 1))
- {
- *errmsg="Could not find first log during relay log initialization";
- goto err;
- }
-
- if (log && rli->relay_log.find_log_pos(&rli->linfo, log, 1))
- {
- *errmsg="Could not find target log during relay log initialization";
- goto err;
- }
- strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->group_relay_log_name)-1);
- strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->event_relay_log_name)-1);
- if (rli->relay_log.is_active(rli->linfo.log_file_name))
- {
- /*
- The IO thread is using this log file.
- In this case, we will use the same IO_CACHE pointer to
- read data as the IO thread is using to write data.
- */
- my_b_seek((rli->cur_log=rli->relay_log.get_log_file()), (off_t)0);
- if (check_binlog_magic(rli->cur_log,errmsg))
- goto err;
- rli->cur_log_old_open_count=rli->relay_log.get_open_count();
- }
- else
- {
- /*
- Open the relay log and set rli->cur_log to point at this one
- */
- if ((rli->cur_log_fd=open_binlog(&rli->cache_buf,
- rli->linfo.log_file_name,errmsg)) < 0)
- goto err;
- rli->cur_log = &rli->cache_buf;
- }
- /*
- In all cases, check_binlog_magic() has been called so we're at offset 4 for
- sure.
- */
- if (pos > BIN_LOG_HEADER_SIZE) /* If pos<=4, we stay at 4 */
- {
- Log_event* ev;
- while (look_for_description_event)
- {
- /*
- Read the possible Format_description_log_event; if position
- was 4, no need, it will be read naturally.
- */
- DBUG_PRINT("info",("looking for a Format_description_log_event"));
-
- if (my_b_tell(rli->cur_log) >= pos)
- break;
-
- /*
- Because of we have rli->data_lock and log_lock, we can safely read an
- event
- */
- if (!(ev=Log_event::read_log_event(rli->cur_log,0,
- rli->relay_log.description_event_for_exec)))
- {
- DBUG_PRINT("info",("could not read event, rli->cur_log->error=%d",
- rli->cur_log->error));
- if (rli->cur_log->error) /* not EOF */
- {
- *errmsg= "I/O error reading event at position 4";
- goto err;
- }
- break;
- }
- else if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
- {
- DBUG_PRINT("info",("found Format_description_log_event"));
- delete rli->relay_log.description_event_for_exec;
- rli->relay_log.description_event_for_exec= (Format_description_log_event*) ev;
- /*
- As ev was returned by read_log_event, it has passed is_valid(), so
- my_malloc() in ctor worked, no need to check again.
- */
- /*
- Ok, we found a Format_description event. But it is not sure that this
- describes the whole relay log; indeed, one can have this sequence
- (starting from position 4):
- Format_desc (of slave)
- Rotate (of master)
- Format_desc (of master)
- So the Format_desc which really describes the rest of the relay log
- is the 3rd event (it can't be further than that, because we rotate
- the relay log when we queue a Rotate event from the master).
- But what describes the Rotate is the first Format_desc.
- So what we do is:
- go on searching for Format_description events, until you exceed the
- position (argument 'pos') or until you find another event than Rotate
- or Format_desc.
- */
- }
- else
- {
- DBUG_PRINT("info",("found event of another type=%d",
- ev->get_type_code()));
- look_for_description_event= (ev->get_type_code() == ROTATE_EVENT);
- delete ev;
- }
- }
- my_b_seek(rli->cur_log,(off_t)pos);
-#ifndef DBUG_OFF
- {
- char llbuf1[22], llbuf2[22];
- DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
- llstr(my_b_tell(rli->cur_log),llbuf1),
- llstr(rli->event_relay_log_pos,llbuf2)));
- }
-#endif
-
- }
-
-err:
- /*
- If we don't purge, we can't honour relay_log_space_limit ;
- silently discard it
- */
- if (!relay_log_purge)
- rli->log_space_limit= 0;
- pthread_cond_broadcast(&rli->data_cond);
-
- pthread_mutex_unlock(log_lock);
-
- if (need_data_lock)
- pthread_mutex_unlock(&rli->data_lock);
- if (!rli->relay_log.description_event_for_exec->is_valid() && !*errmsg)
- *errmsg= "Invalid Format_description log event; could be out of memory";
-
- DBUG_RETURN ((*errmsg) ? 1 : 0);
-}
-
-
-/*
Init function to set up array for errors that should be skipped for slave
SYNOPSIS
@@ -461,174 +245,6 @@ void init_slave_skip_errors(const char* arg)
}
-void st_relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
- bool skip_lock)
-{
- DBUG_ENTER("st_relay_log_info::inc_group_relay_log_pos");
-
- if (!skip_lock)
- pthread_mutex_lock(&data_lock);
- inc_event_relay_log_pos();
- group_relay_log_pos= event_relay_log_pos;
- strmake(group_relay_log_name,event_relay_log_name,
- sizeof(group_relay_log_name)-1);
-
- notify_group_relay_log_name_update();
-
- /*
- If the slave does not support transactions and replicates a transaction,
- users should not trust group_master_log_pos (which they can display with
- SHOW SLAVE STATUS or read from relay-log.info), because to compute
- group_master_log_pos the slave relies on log_pos stored in the master's
- binlog, but if we are in a master's transaction these positions are always
- the BEGIN's one (excepted for the COMMIT), so group_master_log_pos does
- not advance as it should on the non-transactional slave (it advances by
- big leaps, whereas it should advance by small leaps).
- */
- /*
- In 4.x we used the event's len to compute the positions here. This is
- wrong if the event was 3.23/4.0 and has been converted to 5.0, because
- then the event's len is not what is was in the master's binlog, so this
- will make a wrong group_master_log_pos (yes it's a bug in 3.23->4.0
- replication: Exec_master_log_pos is wrong). Only way to solve this is to
- have the original offset of the end of the event the relay log. This is
- what we do in 5.0: log_pos has become "end_log_pos" (because the real use
- of log_pos in 4.0 was to compute the end_log_pos; so better to store
- end_log_pos instead of begin_log_pos.
- If we had not done this fix here, the problem would also have appeared
- when the slave and master are 5.0 but with different event length (for
- example the slave is more recent than the master and features the event
- UID). It would give false MASTER_POS_WAIT, false Exec_master_log_pos in
- SHOW SLAVE STATUS, and so the user would do some CHANGE MASTER using this
- value which would lead to badly broken replication.
- Even the relay_log_pos will be corrupted in this case, because the len is
- the relay log is not "val".
- With the end_log_pos solution, we avoid computations involving lengthes.
- */
- DBUG_PRINT("info", ("log_pos: %lu group_master_log_pos: %lu",
- (long) log_pos, (long) group_master_log_pos));
- if (log_pos) // 3.23 binlogs don't have log_posx
- {
- group_master_log_pos= log_pos;
- }
- pthread_cond_broadcast(&data_cond);
- if (!skip_lock)
- pthread_mutex_unlock(&data_lock);
- DBUG_VOID_RETURN;
-}
-
-
-void st_relay_log_info::close_temporary_tables()
-{
- TABLE *table,*next;
- DBUG_ENTER("st_relay_log_info::close_temporary_tables");
-
- for (table=save_temporary_tables ; table ; table=next)
- {
- next=table->next;
- /*
- Don't ask for disk deletion. For now, anyway they will be deleted when
- slave restarts, but it is a better intention to not delete them.
- */
- DBUG_PRINT("info", ("table: %p", table));
- close_temporary(table, 1, 0);
- }
- save_temporary_tables= 0;
- slave_open_temp_tables= 0;
- DBUG_VOID_RETURN;
-}
-
-/*
- purge_relay_logs()
-
- NOTES
- Assumes to have a run lock on rli and that no slave thread are running.
-*/
-
-int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
- const char** errmsg)
-{
- int error=0;
- DBUG_ENTER("purge_relay_logs");
-
- /*
- Even if rli->inited==0, we still try to empty rli->master_log_* variables.
- Indeed, rli->inited==0 does not imply that they already are empty.
- It could be that slave's info initialization partly succeeded :
- for example if relay-log.info existed but *relay-bin*.*
- have been manually removed, init_relay_log_info reads the old
- relay-log.info and fills rli->master_log_*, then init_relay_log_info
- checks for the existence of the relay log, this fails and
- init_relay_log_info leaves rli->inited to 0.
- In that pathological case, rli->master_log_pos* will be properly reinited
- at the next START SLAVE (as RESET SLAVE or CHANGE
- MASTER, the callers of purge_relay_logs, will delete bogus *.info files
- or replace them with correct files), however if the user does SHOW SLAVE
- STATUS before START SLAVE, he will see old, confusing rli->master_log_*.
- In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
- to display fine in any case.
- */
-
- rli->group_master_log_name[0]= 0;
- rli->group_master_log_pos= 0;
-
- if (!rli->inited)
- {
- DBUG_PRINT("info", ("rli->inited == 0"));
- DBUG_RETURN(0);
- }
-
- DBUG_ASSERT(rli->slave_running == 0);
- DBUG_ASSERT(rli->mi->slave_running == 0);
-
- rli->slave_skip_counter=0;
- pthread_mutex_lock(&rli->data_lock);
-
- /*
- we close the relay log fd possibly left open by the slave SQL thread,
- to be able to delete it; the relay log fd possibly left open by the slave
- I/O thread will be closed naturally in reset_logs() by the
- close(LOG_CLOSE_TO_BE_OPENED) call
- */
- if (rli->cur_log_fd >= 0)
- {
- end_io_cache(&rli->cache_buf);
- my_close(rli->cur_log_fd, MYF(MY_WME));
- rli->cur_log_fd= -1;
- }
-
- if (rli->relay_log.reset_logs(thd))
- {
- *errmsg = "Failed during log reset";
- error=1;
- goto err;
- }
- /* Save name of used relay log file */
- strmake(rli->group_relay_log_name, rli->relay_log.get_log_fname(),
- sizeof(rli->group_relay_log_name)-1);
- strmake(rli->event_relay_log_name, rli->relay_log.get_log_fname(),
- sizeof(rli->event_relay_log_name)-1);
- rli->group_relay_log_pos= rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
- if (count_relay_log_space(rli))
- {
- *errmsg= "Error counting relay log space";
- goto err;
- }
- if (!just_reset)
- error= init_relay_log_pos(rli, rli->group_relay_log_name,
- rli->group_relay_log_pos,
- 0 /* do not need data lock */, errmsg, 0);
-
-err:
-#ifndef DBUG_OFF
- char buf[22];
-#endif
- DBUG_PRINT("info",("log_space_total: %s",llstr(rli->log_space_total,buf)));
- pthread_mutex_unlock(&rli->data_lock);
- DBUG_RETURN(error);
-}
-
-
int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
{
DBUG_ENTER("terminate_slave_threads");
@@ -1023,7 +639,7 @@ const char *print_slave_db_safe(const char* db)
DBUG_RETURN((db ? db : ""));
}
-static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
const char *default_val)
{
uint length;
@@ -1054,7 +670,7 @@ static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
}
-static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
+int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
{
char buf[32];
DBUG_ENTER("init_intvar_from_file");
@@ -1456,261 +1072,6 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name,
}
-void end_master_info(MASTER_INFO* mi)
-{
- DBUG_ENTER("end_master_info");
-
- if (!mi->inited)
- DBUG_VOID_RETURN;
- end_relay_log_info(&mi->rli);
- if (mi->fd >= 0)
- {
- end_io_cache(&mi->file);
- (void)my_close(mi->fd, MYF(MY_WME));
- mi->fd = -1;
- }
- mi->inited = 0;
-
- DBUG_VOID_RETURN;
-}
-
-
-static int init_relay_log_info(RELAY_LOG_INFO* rli,
- const char* info_fname)
-{
- char fname[FN_REFLEN+128];
- int info_fd;
- const char* msg = 0;
- int error = 0;
- DBUG_ENTER("init_relay_log_info");
- DBUG_ASSERT(!rli->no_storage); // Don't init if there is no storage
-
- if (rli->inited) // Set if this function called
- DBUG_RETURN(0);
- fn_format(fname, info_fname, mysql_data_home, "", 4+32);
- pthread_mutex_lock(&rli->data_lock);
- info_fd = rli->info_fd;
- rli->cur_log_fd = -1;
- rli->slave_skip_counter=0;
- rli->abort_pos_wait=0;
- rli->log_space_limit= relay_log_space_limit;
- rli->log_space_total= 0;
- rli->tables_to_lock= 0;
- rli->tables_to_lock_count= 0;
-
- /*
- The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
- Note that the I/O thread flushes it to disk after writing every
- event, in flush_master_info(mi, 1).
- */
-
- /*
- For the maximum log size, we choose max_relay_log_size if it is
- non-zero, max_binlog_size otherwise. If later the user does SET
- GLOBAL on one of these variables, fix_max_binlog_size and
- fix_max_relay_log_size will reconsider the choice (for example
- if the user changes max_relay_log_size to zero, we have to
- switch to using max_binlog_size for the relay log) and update
- rli->relay_log.max_size (and mysql_bin_log.max_size).
- */
- {
- char buf[FN_REFLEN];
- const char *ln;
- static bool name_warning_sent= 0;
- ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
- 1, buf);
- /* We send the warning only at startup, not after every RESET SLAVE */
- if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
- {
- /*
- User didn't give us info to name the relay log index file.
- Picking `hostname`-relay-bin.index like we do, causes replication to
- fail if this slave's hostname is changed later. So, we would like to
- instead require a name. But as we don't want to break many existing
- setups, we only give warning, not error.
- */
- sql_print_warning("Neither --relay-log nor --relay-log-index were used;"
- " so replication "
- "may break when this MySQL server acts as a "
- "slave and has his hostname changed!! Please "
- "use '--relay-log=%s' to avoid this problem.", ln);
- name_warning_sent= 1;
- }
- /*
- note, that if open() fails, we'll still have index file open
- but a destructor will take care of that
- */
- if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
- rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
- (max_relay_log_size ? max_relay_log_size :
- max_binlog_size), 1))
- {
- pthread_mutex_unlock(&rli->data_lock);
- sql_print_error("Failed in open_log() called from init_relay_log_info()");
- DBUG_RETURN(1);
- }
- }
-
- /* if file does not exist */
- if (access(fname,F_OK))
- {
- /*
- If someone removed the file from underneath our feet, just close
- the old descriptor and re-create the old file
- */
- if (info_fd >= 0)
- my_close(info_fd, MYF(MY_WME));
- if ((info_fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
- {
- sql_print_error("Failed to create a new relay log info file (\
-file '%s', errno %d)", fname, my_errno);
- msg= current_thd->net.last_error;
- goto err;
- }
- if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on relay log info file '%s'",
- fname);
- msg= current_thd->net.last_error;
- goto err;
- }
-
- /* Init relay log with first entry in the relay index file */
- if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
- &msg, 0))
- {
- sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
- goto err;
- }
- rli->group_master_log_name[0]= 0;
- rli->group_master_log_pos= 0;
- rli->info_fd= info_fd;
- }
- else // file exists
- {
- if (info_fd >= 0)
- reinit_io_cache(&rli->info_file, READ_CACHE, 0L,0,0);
- else
- {
- int error=0;
- if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
- {
- sql_print_error("\
-Failed to open the existing relay log info file '%s' (errno %d)",
- fname, my_errno);
- error= 1;
- }
- else if (init_io_cache(&rli->info_file, info_fd,
- IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on relay log info file '%s'",
- fname);
- error= 1;
- }
- if (error)
- {
- if (info_fd >= 0)
- my_close(info_fd, MYF(0));
- rli->info_fd= -1;
- rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
- pthread_mutex_unlock(&rli->data_lock);
- DBUG_RETURN(1);
- }
- }
-
- rli->info_fd = info_fd;
- int relay_log_pos, master_log_pos;
- if (init_strvar_from_file(rli->group_relay_log_name,
- sizeof(rli->group_relay_log_name),
- &rli->info_file, "") ||
- init_intvar_from_file(&relay_log_pos,
- &rli->info_file, BIN_LOG_HEADER_SIZE) ||
- init_strvar_from_file(rli->group_master_log_name,
- sizeof(rli->group_master_log_name),
- &rli->info_file, "") ||
- init_intvar_from_file(&master_log_pos, &rli->info_file, 0))
- {
- msg="Error reading slave log configuration";
- goto err;
- }
- strmake(rli->event_relay_log_name,rli->group_relay_log_name,
- sizeof(rli->event_relay_log_name)-1);
- rli->group_relay_log_pos= rli->event_relay_log_pos= relay_log_pos;
- rli->group_master_log_pos= master_log_pos;
-
- if (init_relay_log_pos(rli,
- rli->group_relay_log_name,
- rli->group_relay_log_pos,
- 0 /* no data lock*/,
- &msg, 0))
- {
- char llbuf[22];
- sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)",
- rli->group_relay_log_name,
- llstr(rli->group_relay_log_pos, llbuf));
- goto err;
- }
- }
-
-#ifndef DBUG_OFF
- {
- char llbuf1[22], llbuf2[22];
- DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
- llstr(my_b_tell(rli->cur_log),llbuf1),
- llstr(rli->event_relay_log_pos,llbuf2)));
- DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
- DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->event_relay_log_pos);
- }
-#endif
-
- /*
- Now change the cache from READ to WRITE - must do this
- before flush_relay_log_info
- */
- reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1);
- if ((error= flush_relay_log_info(rli)))
- sql_print_error("Failed to flush relay log info file");
- if (count_relay_log_space(rli))
- {
- msg="Error counting relay log space";
- goto err;
- }
- rli->inited= 1;
- pthread_mutex_unlock(&rli->data_lock);
- DBUG_RETURN(error);
-
-err:
- sql_print_error(msg);
- end_io_cache(&rli->info_file);
- if (info_fd >= 0)
- my_close(info_fd, MYF(0));
- rli->info_fd= -1;
- rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
- pthread_mutex_unlock(&rli->data_lock);
- DBUG_RETURN(1);
-}
-
-
-static inline int add_relay_log(RELAY_LOG_INFO* rli,LOG_INFO* linfo)
-{
- MY_STAT s;
- DBUG_ENTER("add_relay_log");
- if (!my_stat(linfo->log_file_name,&s,MYF(0)))
- {
- sql_print_error("log %s listed in the index, but failed to stat",
- linfo->log_file_name);
- DBUG_RETURN(1);
- }
- rli->log_space_total += s.st_size;
-#ifndef DBUG_OFF
- char buf[22];
- DBUG_PRINT("info",("log_space_total: %s", llstr(rli->log_space_total,buf)));
-#endif
- DBUG_RETURN(0);
-}
-
-
static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli)
{
bool slave_killed=0;
@@ -1733,31 +1094,6 @@ Waiting for the slave SQL thread to free enough relay log space");
}
-static int count_relay_log_space(RELAY_LOG_INFO* rli)
-{
- LOG_INFO linfo;
- DBUG_ENTER("count_relay_log_space");
- rli->log_space_total= 0;
- if (rli->relay_log.find_log_pos(&linfo, NullS, 1))
- {
- sql_print_error("Could not find first log while counting relay log space");
- DBUG_RETURN(1);
- }
- do
- {
- if (add_relay_log(rli,&linfo))
- DBUG_RETURN(1);
- } while (!rli->relay_log.find_next_log(&linfo, 1));
- /*
- As we have counted everything, including what may have written in a
- preceding write, we must reset bytes_written, or we may count some space
- twice.
- */
- rli->relay_log.reset_bytes_written();
- DBUG_RETURN(0);
-}
-
-
/*
Builds a Rotate from the ignored events' info and writes it to relay log.
@@ -1811,284 +1147,6 @@ static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi)
}
-void init_master_info_with_options(MASTER_INFO* mi)
-{
- DBUG_ENTER("init_master_info_with_options");
-
- mi->master_log_name[0] = 0;
- mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
-
- if (master_host)
- strmake(mi->host, master_host, sizeof(mi->host) - 1);
- if (master_user)
- strmake(mi->user, master_user, sizeof(mi->user) - 1);
- if (master_password)
- strmake(mi->password, master_password, MAX_PASSWORD_LENGTH);
- mi->port = master_port;
- mi->connect_retry = master_connect_retry;
-
- mi->ssl= master_ssl;
- if (master_ssl_ca)
- strmake(mi->ssl_ca, master_ssl_ca, sizeof(mi->ssl_ca)-1);
- if (master_ssl_capath)
- strmake(mi->ssl_capath, master_ssl_capath, sizeof(mi->ssl_capath)-1);
- if (master_ssl_cert)
- strmake(mi->ssl_cert, master_ssl_cert, sizeof(mi->ssl_cert)-1);
- if (master_ssl_cipher)
- strmake(mi->ssl_cipher, master_ssl_cipher, sizeof(mi->ssl_cipher)-1);
- if (master_ssl_key)
- strmake(mi->ssl_key, master_ssl_key, sizeof(mi->ssl_key)-1);
- DBUG_VOID_RETURN;
-}
-
-void clear_slave_error(RELAY_LOG_INFO* rli)
-{
- DBUG_ENTER("clear_slave_error");
-
- /* Clear the errors displayed by SHOW SLAVE STATUS */
- rli->last_slave_error[0]= 0;
- rli->last_slave_errno= 0;
- DBUG_VOID_RETURN;
-}
-
-/*
- Reset UNTIL condition for RELAY_LOG_INFO
- SYNOPSYS
- clear_until_condition()
- rli - RELAY_LOG_INFO structure where UNTIL condition should be reset
- */
-void clear_until_condition(RELAY_LOG_INFO* rli)
-{
- DBUG_ENTER("clear_until_condition");
-
- rli->until_condition= RELAY_LOG_INFO::UNTIL_NONE;
- rli->until_log_name[0]= 0;
- rli->until_log_pos= 0;
- DBUG_VOID_RETURN;
-}
-
-
-#define LINES_IN_MASTER_INFO_WITH_SSL 14
-
-
-int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
- const char* slave_info_fname,
- bool abort_if_no_master_info_file,
- int thread_mask)
-{
- int fd,error;
- char fname[FN_REFLEN+128];
- DBUG_ENTER("init_master_info");
-
- if (mi->inited)
- {
- /*
- We have to reset read position of relay-log-bin as we may have
- already been reading from 'hotlog' when the slave was stopped
- last time. If this case pos_in_file would be set and we would
- get a crash when trying to read the signature for the binary
- relay log.
-
- We only rewind the read position if we are starting the SQL
- thread. The handle_slave_sql thread assumes that the read
- position is at the beginning of the file, and will read the
- "signature" and then fast-forward to the last position read.
- */
- if (thread_mask & SLAVE_SQL)
- {
- my_b_seek(mi->rli.cur_log, (my_off_t) 0);
- }
- DBUG_RETURN(0);
- }
-
- mi->mysql=0;
- mi->file_id=1;
- fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
-
- /*
- We need a mutex while we are changing master info parameters to
- keep other threads from reading bogus info
- */
-
- pthread_mutex_lock(&mi->data_lock);
- fd = mi->fd;
-
- /* does master.info exist ? */
-
- if (access(fname,F_OK))
- {
- if (abort_if_no_master_info_file)
- {
- pthread_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(0);
- }
- /*
- if someone removed the file from underneath our feet, just close
- the old descriptor and re-create the old file
- */
- if (fd >= 0)
- my_close(fd, MYF(MY_WME));
- if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
- {
- sql_print_error("Failed to create a new master info file (\
-file '%s', errno %d)", fname, my_errno);
- goto err;
- }
- if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on master info file (\
-file '%s')", fname);
- goto err;
- }
-
- mi->fd = fd;
- init_master_info_with_options(mi);
-
- }
- else // file exists
- {
- if (fd >= 0)
- reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
- else
- {
- if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
- {
- sql_print_error("Failed to open the existing master info file (\
-file '%s', errno %d)", fname, my_errno);
- goto err;
- }
- if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
- 0, MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on master info file (\
-file '%s')", fname);
- goto err;
- }
- }
-
- mi->fd = fd;
- int port, connect_retry, master_log_pos, ssl= 0, lines;
- char *first_non_digit;
-
- /*
- Starting from 4.1.x master.info has new format. Now its
- first line contains number of lines in file. By reading this
- number we will be always distinguish to which version our
- master.info corresponds to. We can't simply count lines in
- file since versions before 4.1.x could generate files with more
- lines than needed.
- If first line doesn't contain a number or contain number less than
- 14 then such file is treated like file from pre 4.1.1 version.
- There is no ambiguity when reading an old master.info, as before
- 4.1.1, the first line contained the binlog's name, which is either
- empty or has an extension (contains a '.'), so can't be confused
- with an integer.
-
- So we're just reading first line and trying to figure which version
- is this.
- */
-
- /*
- The first row is temporarily stored in mi->master_log_name,
- if it is line count and not binlog name (new format) it will be
- overwritten by the second row later.
- */
- if (init_strvar_from_file(mi->master_log_name,
- sizeof(mi->master_log_name), &mi->file,
- ""))
- goto errwithmsg;
-
- lines= strtoul(mi->master_log_name, &first_non_digit, 10);
-
- if (mi->master_log_name[0]!='\0' &&
- *first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
- { // Seems to be new format
- if (init_strvar_from_file(mi->master_log_name,
- sizeof(mi->master_log_name), &mi->file, ""))
- goto errwithmsg;
- }
- else
- lines= 7;
-
- if (init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
- init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
- master_host) ||
- init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
- master_user) ||
- init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1,
- &mi->file, master_password) ||
- init_intvar_from_file(&port, &mi->file, master_port) ||
- init_intvar_from_file(&connect_retry, &mi->file,
- master_connect_retry))
- goto errwithmsg;
-
- /*
- If file has ssl part use it even if we have server without
- SSL support. But these option will be ignored later when
- slave will try connect to master, so in this case warning
- is printed.
- */
- if (lines >= LINES_IN_MASTER_INFO_WITH_SSL &&
- (init_intvar_from_file(&ssl, &mi->file, master_ssl) ||
- init_strvar_from_file(mi->ssl_ca, sizeof(mi->ssl_ca),
- &mi->file, master_ssl_ca) ||
- init_strvar_from_file(mi->ssl_capath, sizeof(mi->ssl_capath),
- &mi->file, master_ssl_capath) ||
- init_strvar_from_file(mi->ssl_cert, sizeof(mi->ssl_cert),
- &mi->file, master_ssl_cert) ||
- init_strvar_from_file(mi->ssl_cipher, sizeof(mi->ssl_cipher),
- &mi->file, master_ssl_cipher) ||
- init_strvar_from_file(mi->ssl_key, sizeof(mi->ssl_key),
- &mi->file, master_ssl_key)))
- goto errwithmsg;
-#ifndef HAVE_OPENSSL
- if (ssl)
- sql_print_warning("SSL information in the master info file "
- "('%s') are ignored because this MySQL slave was compiled "
- "without SSL support.", fname);
-#endif /* HAVE_OPENSSL */
-
- /*
- This has to be handled here as init_intvar_from_file can't handle
- my_off_t types
- */
- mi->master_log_pos= (my_off_t) master_log_pos;
- mi->port= (uint) port;
- mi->connect_retry= (uint) connect_retry;
- mi->ssl= (my_bool) ssl;
- }
- DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
- mi->master_log_name,
- (ulong) mi->master_log_pos));
-
- mi->rli.mi = mi;
- if (init_relay_log_info(&mi->rli, slave_info_fname))
- goto err;
-
- mi->inited = 1;
- // now change cache READ -> WRITE - must do this before flush_master_info
- reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
- if ((error=test(flush_master_info(mi, 1))))
- sql_print_error("Failed to flush master info file");
- pthread_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(error);
-
-errwithmsg:
- sql_print_error("Error reading master configuration");
-
-err:
- if (fd >= 0)
- {
- my_close(fd, MYF(0));
- end_io_cache(&mi->file);
- }
- mi->fd= -1;
- pthread_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(1);
-}
-
-
int register_slave_on_master(MYSQL* mysql)
{
char buf[1024], *pos= buf;
@@ -2307,313 +1365,6 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
DBUG_RETURN(FALSE);
}
-/*
- RETURN
- 2 - flush relay log failed
- 1 - flush master info failed
- 0 - all ok
-*/
-int flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
-{
- IO_CACHE* file = &mi->file;
- char lbuf[22];
- DBUG_ENTER("flush_master_info");
- DBUG_PRINT("enter",("master_pos: %ld", (long) mi->master_log_pos));
-
- /*
- Flush the relay log to disk. If we don't do it, then the relay log while
- have some part (its last kilobytes) in memory only, so if the slave server
- dies now, with, say, from master's position 100 to 150 in memory only (not
- on disk), and with position 150 in master.info, then when the slave
- restarts, the I/O thread will fetch binlogs from 150, so in the relay log
- we will have "[0, 100] U [150, infinity[" and nobody will notice it, so the
- SQL thread will jump from 100 to 150, and replication will silently break.
-
- When we come to this place in code, relay log may or not be initialized;
- the caller is responsible for setting 'flush_relay_log_cache' accordingly.
- */
- if (flush_relay_log_cache &&
- flush_io_cache(mi->rli.relay_log.get_log_file()))
- DBUG_RETURN(2);
-
- /*
- We flushed the relay log BEFORE the master.info file, because if we crash
- now, we will get a duplicate event in the relay log at restart. If we
- flushed in the other order, we would get a hole in the relay log.
- And duplicate is better than hole (with a duplicate, in later versions we
- can add detection and scrap one event; with a hole there's nothing we can
- do).
- */
-
- /*
- In certain cases this code may create master.info files that seems
- corrupted, because of extra lines filled with garbage in the end
- file (this happens if new contents take less space than previous
- contents of file). But because of number of lines in the first line
- of file we don't care about this garbage.
- */
-
- my_b_seek(file, 0L);
- my_b_printf(file, "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n",
- LINES_IN_MASTER_INFO_WITH_SSL,
- mi->master_log_name, llstr(mi->master_log_pos, lbuf),
- mi->host, mi->user,
- mi->password, mi->port, mi->connect_retry,
- (int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
- mi->ssl_cipher, mi->ssl_key);
- DBUG_RETURN(-flush_io_cache(file));
-}
-
-
-st_relay_log_info::st_relay_log_info()
- :no_storage(FALSE), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
- cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0),
- ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
- abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0),
- inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
- until_log_pos(0), retried_trans(0),
- tables_to_lock(0), tables_to_lock_count(0),
- m_reload_flags(RELOAD_NONE_F),
- unsafe_to_stop_at(0)
-{
- DBUG_ENTER("st_relay_log_info::st_relay_log_info");
-
- group_relay_log_name[0]= event_relay_log_name[0]=
- group_master_log_name[0]= 0;
- last_slave_error[0]= until_log_name[0]= ign_master_log_name_end[0]= 0;
- bzero((char*) &info_file, sizeof(info_file));
- bzero((char*) &cache_buf, sizeof(cache_buf));
- cached_charset_invalidate();
- pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&log_space_lock, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&data_cond, NULL);
- pthread_cond_init(&start_cond, NULL);
- pthread_cond_init(&stop_cond, NULL);
- pthread_cond_init(&log_space_cond, NULL);
- relay_log.init_pthread_objects();
- DBUG_VOID_RETURN;
-}
-
-
-st_relay_log_info::~st_relay_log_info()
-{
- DBUG_ENTER("st_relay_log_info::~st_relay_log_info");
-
- pthread_mutex_destroy(&run_lock);
- pthread_mutex_destroy(&data_lock);
- pthread_mutex_destroy(&log_space_lock);
- pthread_cond_destroy(&data_cond);
- pthread_cond_destroy(&start_cond);
- pthread_cond_destroy(&stop_cond);
- pthread_cond_destroy(&log_space_cond);
- relay_log.cleanup();
- DBUG_VOID_RETURN;
-}
-
-/*
- Waits until the SQL thread reaches (has executed up to) the
- log/position or timed out.
-
- SYNOPSIS
- wait_for_pos()
- thd client thread that sent SELECT MASTER_POS_WAIT
- log_name log name to wait for
- log_pos position to wait for
- timeout timeout in seconds before giving up waiting
-
- NOTES
- timeout is longlong whereas it should be ulong ; but this is
- to catch if the user submitted a negative timeout.
-
- RETURN VALUES
- -2 improper arguments (log_pos<0)
- or slave not running, or master info changed
- during the function's execution,
- or client thread killed. -2 is translated to NULL by caller
- -1 timed out
- >=0 number of log events the function had to wait
- before reaching the desired log/position
- */
-
-int st_relay_log_info::wait_for_pos(THD* thd, String* log_name,
- longlong log_pos,
- longlong timeout)
-{
- int event_count = 0;
- ulong init_abort_pos_wait;
- int error=0;
- struct timespec abstime; // for timeout checking
- const char *msg;
- DBUG_ENTER("st_relay_log_info::wait_for_pos");
-
- if (!inited)
- DBUG_RETURN(-1);
-
- DBUG_PRINT("enter",("log_name: '%s' log_pos: %lu timeout: %lu",
- log_name->c_ptr(), (ulong) log_pos, (ulong) timeout));
-
- set_timespec(abstime,timeout);
- pthread_mutex_lock(&data_lock);
- msg= thd->enter_cond(&data_cond, &data_lock,
- "Waiting for the slave SQL thread to "
- "advance position");
- /*
- This function will abort when it notices that some CHANGE MASTER or
- RESET MASTER has changed the master info.
- To catch this, these commands modify abort_pos_wait ; We just monitor
- abort_pos_wait and see if it has changed.
- Why do we have this mechanism instead of simply monitoring slave_running
- in the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that
- the SQL thread be stopped?
- This is becasue if someones does:
- STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE;
- the change may happen very quickly and we may not notice that
- slave_running briefly switches between 1/0/1.
- */
- init_abort_pos_wait= abort_pos_wait;
-
- /*
- We'll need to
- handle all possible log names comparisons (e.g. 999 vs 1000).
- We use ulong for string->number conversion ; this is no
- stronger limitation than in find_uniq_filename in sql/log.cc
- */
- ulong log_name_extension;
- char log_name_tmp[FN_REFLEN]; //make a char[] from String
-
- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
-
- char *p= fn_ext(log_name_tmp);
- char *p_end;
- if (!*p || log_pos<0)
- {
- error= -2; //means improper arguments
- goto err;
- }
- // Convert 0-3 to 4
- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
- /* p points to '.' */
- log_name_extension= strtoul(++p, &p_end, 10);
- /*
- p_end points to the first invalid character.
- If it equals to p, no digits were found, error.
- If it contains '\0' it means conversion went ok.
- */
- if (p_end==p || *p_end)
- {
- error= -2;
- goto err;
- }
-
- /* The "compare and wait" main loop */
- while (!thd->killed &&
- init_abort_pos_wait == abort_pos_wait &&
- slave_running)
- {
- bool pos_reached;
- int cmp_result= 0;
-
- DBUG_PRINT("info",
- ("init_abort_pos_wait: %ld abort_pos_wait: %ld",
- init_abort_pos_wait, abort_pos_wait));
- DBUG_PRINT("info",("group_master_log_name: '%s' pos: %lu",
- group_master_log_name, (ulong) group_master_log_pos));
-
- /*
- group_master_log_name can be "", if we are just after a fresh
- replication start or after a CHANGE MASTER TO MASTER_HOST/PORT
- (before we have executed one Rotate event from the master) or
- (rare) if the user is doing a weird slave setup (see next
- paragraph). If group_master_log_name is "", we assume we don't
- have enough info to do the comparison yet, so we just wait until
- more data. In this case master_log_pos is always 0 except if
- somebody (wrongly) sets this slave to be a slave of itself
- without using --replicate-same-server-id (an unsupported
- configuration which does nothing), then group_master_log_pos
- will grow and group_master_log_name will stay "".
- */
- if (*group_master_log_name)
- {
- char *basename= (group_master_log_name +
- dirname_length(group_master_log_name));
- /*
- First compare the parts before the extension.
- Find the dot in the master's log basename,
- and protect against user's input error :
- if the names do not match up to '.' included, return error
- */
- char *q= (char*)(fn_ext(basename)+1);
- if (strncmp(basename, log_name_tmp, (int)(q-basename)))
- {
- error= -2;
- break;
- }
- // Now compare extensions.
- char *q_end;
- ulong group_master_log_name_extension= strtoul(q, &q_end, 10);
- if (group_master_log_name_extension < log_name_extension)
- cmp_result= -1 ;
- else
- cmp_result= (group_master_log_name_extension > log_name_extension) ? 1 : 0 ;
-
- pos_reached= ((!cmp_result && group_master_log_pos >= (ulonglong)log_pos) ||
- cmp_result > 0);
- if (pos_reached || thd->killed)
- break;
- }
-
- //wait for master update, with optional timeout.
-
- DBUG_PRINT("info",("Waiting for master update"));
- /*
- We are going to pthread_cond_(timed)wait(); if the SQL thread stops it
- will wake us up.
- */
- if (timeout > 0)
- {
- /*
- Note that pthread_cond_timedwait checks for the timeout
- before for the condition ; i.e. it returns ETIMEDOUT
- if the system time equals or exceeds the time specified by abstime
- before the condition variable is signaled or broadcast, _or_ if
- the absolute time specified by abstime has already passed at the time
- of the call.
- For that reason, pthread_cond_timedwait will do the "timeoutting" job
- even if its condition is always immediately signaled (case of a loaded
- master).
- */
- error=pthread_cond_timedwait(&data_cond, &data_lock, &abstime);
- }
- else
- pthread_cond_wait(&data_cond, &data_lock);
- DBUG_PRINT("info",("Got signal of master update or timed out"));
- if (error == ETIMEDOUT || error == ETIME)
- {
- error= -1;
- break;
- }
- error=0;
- event_count++;
- DBUG_PRINT("info",("Testing if killed or SQL thread not running"));
- }
-
-err:
- thd->exit_cond(msg);
- DBUG_PRINT("exit",("killed: %d abort: %d slave_running: %d \
-improper_arguments: %d timed_out: %d",
- thd->killed_errno(),
- (int) (init_abort_pos_wait != abort_pos_wait),
- (int) slave_running,
- (int) (error == -2),
- (int) (error == -1)));
- if (thd->killed || init_abort_pos_wait != abort_pos_wait ||
- !slave_running)
- {
- error= -2;
- }
- DBUG_RETURN( error ? error : event_count );
-}
void set_slave_thread_options(THD* thd)
{
@@ -2872,119 +1623,6 @@ int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error)
}
}
-/*
- Check if condition stated in UNTIL clause of START SLAVE is reached.
- SYNOPSYS
- st_relay_log_info::is_until_satisfied()
- DESCRIPTION
- Checks if UNTIL condition is reached. Uses caching result of last
- comparison of current log file name and target log file name. So cached
- value should be invalidated if current log file name changes
- (see st_relay_log_info::notify_... functions).
-
- This caching is needed to avoid of expensive string comparisons and
- strtol() conversions needed for log names comparison. We don't need to
- compare them each time this function is called, we only need to do this
- when current log name changes. If we have UNTIL_MASTER_POS condition we
- need to do this only after Rotate_log_event::exec_event() (which is
- rare, so caching gives real benifit), and if we have UNTIL_RELAY_POS
- condition then we should invalidate cached comarison value after
- inc_group_relay_log_pos() which called for each group of events (so we
- have some benefit if we have something like queries that use
- autoincrement or if we have transactions).
-
- Should be called ONLY if until_condition != UNTIL_NONE !
- RETURN VALUE
- true - condition met or error happened (condition seems to have
- bad log file name)
- false - condition not met
-*/
-
-bool st_relay_log_info::is_until_satisfied()
-{
- const char *log_name;
- ulonglong log_pos;
- DBUG_ENTER("st_relay_log_info::is_until_satisfied");
-
- DBUG_ASSERT(until_condition != UNTIL_NONE);
-
- if (until_condition == UNTIL_MASTER_POS)
- {
- log_name= group_master_log_name;
- log_pos= group_master_log_pos;
- }
- else
- { /* until_condition == UNTIL_RELAY_POS */
- log_name= group_relay_log_name;
- log_pos= group_relay_log_pos;
- }
-
- if (until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_UNKNOWN)
- {
- /*
- We have no cached comparison results so we should compare log names
- and cache result.
- If we are after RESET SLAVE, and the SQL slave thread has not processed
- any event yet, it could be that group_master_log_name is "". In that case,
- just wait for more events (as there is no sensible comparison to do).
- */
-
- if (*log_name)
- {
- const char *basename= log_name + dirname_length(log_name);
-
- const char *q= (const char*)(fn_ext(basename)+1);
- if (strncmp(basename, until_log_name, (int)(q-basename)) == 0)
- {
- /* Now compare extensions. */
- char *q_end;
- ulong log_name_extension= strtoul(q, &q_end, 10);
- if (log_name_extension < until_log_name_extension)
- until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_LESS;
- else
- until_log_names_cmp_result=
- (log_name_extension > until_log_name_extension) ?
- UNTIL_LOG_NAMES_CMP_GREATER : UNTIL_LOG_NAMES_CMP_EQUAL ;
- }
- else
- {
- /* Probably error so we aborting */
- sql_print_error("Slave SQL thread is stopped because UNTIL "
- "condition is bad.");
- DBUG_RETURN(TRUE);
- }
- }
- else
- DBUG_RETURN(until_log_pos == 0);
- }
-
- DBUG_RETURN(((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL &&
- log_pos >= until_log_pos) ||
- until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
-}
-
-
-void st_relay_log_info::cached_charset_invalidate()
-{
- DBUG_ENTER("st_relay_log_info::cached_charset_invalidate");
-
- /* Full of zeroes means uninitialized. */
- bzero(cached_charset, sizeof(cached_charset));
- DBUG_VOID_RETURN;
-}
-
-
-bool st_relay_log_info::cached_charset_compare(char *charset)
-{
- DBUG_ENTER("st_relay_log_info::cached_charset_compare");
-
- if (bcmp(cached_charset, charset, sizeof(cached_charset)))
- {
- memcpy(cached_charset, charset, sizeof(cached_charset));
- DBUG_RETURN(1);
- }
- DBUG_RETURN(0);
-}
/*
Check if the current error is of temporary nature of not.
@@ -3176,6 +1814,8 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
We were in a transaction which has been rolled back because of a
temporary error;
let's seek back to BEGIN log event and retry it all again.
+ Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
+ there is no rollback since 5.0.13 (ref: manual).
We have to not only seek but also
a) init_master_info(), to seek back to hot relay log's start for later
(for when we will come back to this hot log after re-processing the
@@ -3632,7 +2272,7 @@ pthread_handler_t handle_slave_sql(void *arg)
now.
But the master timestamp is reset by RESET SLAVE & CHANGE MASTER.
*/
- clear_slave_error(rli);
+ rli->clear_slave_error();
//tell the I/O thread to take relay_log_space_limit into account from now on
pthread_mutex_lock(&rli->log_space_lock);
@@ -4455,7 +3095,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
'%s@%s:%d': \
Error: '%s' errno: %d retry-time: %d retries: %lu",
(reconnect ? "reconnecting" : "connecting"),
- mi->user,mi->host,mi->port,
+ mi->user, mi->host, mi->port,
mysql_error(mysql), last_errno,
mi->connect_retry,
master_retry_count);
@@ -4990,121 +3630,6 @@ end:
DBUG_VOID_RETURN;
}
-/*
- Some system tables needed to be re-read by the MySQL server after it has
- updated them; in statement-based replication, the GRANT and other commands
- are sent verbatim to the slave which then reloads; in row-based replication,
- changes to these tables are done through ordinary Rows binlog events, so
- master must add some flag for the slave to know it has to reload the tables.
-*/
-struct st_reload_entry
-{
- char const *table;
- st_relay_log_info::enum_reload_flag flag;
-};
-
-/*
- Sorted array of table names, please keep it sorted since we are
- using bsearch() on it below.
- */
-static st_reload_entry s_mysql_tables[] =
-{
- { "columns_priv", st_relay_log_info::RELOAD_GRANT_F },
- { "db", st_relay_log_info::RELOAD_ACCESS_F },
- { "host", st_relay_log_info::RELOAD_ACCESS_F },
- { "procs_priv", st_relay_log_info::RELOAD_GRANT_F },
- { "tables_priv", st_relay_log_info::RELOAD_GRANT_F },
- { "user", st_relay_log_info::RELOAD_ACCESS_F }
-};
-
-static const my_size_t s_mysql_tables_size =
- sizeof(s_mysql_tables)/sizeof(*s_mysql_tables);
-
-static int reload_entry_compare(const void *lhs, const void *rhs)
-{
- const char *lstr = static_cast<const char *>(lhs);
- const char *rstr = static_cast<const st_reload_entry*>(rhs)->table;
- DBUG_ENTER("reload_entry_compare");
-
- DBUG_RETURN(strcmp(lstr, rstr));
-}
-
-void st_relay_log_info::touching_table(char const* db, char const* table,
- ulong table_id)
-{
- DBUG_ENTER("st_relay_log_info::touching_table");
-
- if (strcmp(db,"mysql") == 0)
- {
-#if defined(HAVE_BSEARCH) && defined(HAVE_SIZE_T)
- void *const ptr= bsearch(table, s_mysql_tables,
- s_mysql_tables_size,
- sizeof(*s_mysql_tables), reload_entry_compare);
- st_reload_entry const *const entry= static_cast<st_reload_entry*>(ptr);
-#else
- /*
- Fall back to full scan, there are few rows anyway and updating the
- "mysql" database is rare.
- */
- st_reload_entry const *entry= s_mysql_tables;
- for ( ; entry < s_mysql_tables + s_mysql_tables_size ; entry++)
- if (reload_entry_compare(table, entry) == 0)
- break;
-#endif
- if (entry)
- m_reload_flags|= entry->flag;
- }
- DBUG_VOID_RETURN;
-}
-
-void st_relay_log_info::transaction_end(THD* thd)
-{
- DBUG_ENTER("st_relay_log_info::transaction_end");
-
- if (m_reload_flags != RELOAD_NONE_F)
- {
- if (m_reload_flags & RELOAD_ACCESS_F)
- acl_reload(thd);
-
- if (m_reload_flags & RELOAD_GRANT_F)
- grant_reload(thd);
-
- m_reload_flags= RELOAD_NONE_F;
- }
- DBUG_VOID_RETURN;
-}
-
-#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-void st_relay_log_info::cleanup_context(THD *thd, bool error)
-{
- DBUG_ENTER("st_relay_log_info::cleanup_context");
-
- DBUG_ASSERT(sql_thd == thd);
- /*
- 1) Instances of Table_map_log_event, if ::exec_event() was called on them,
- may have opened tables, which we cannot be sure have been closed (because
- maybe the Rows_log_event have not been found or will not be, because slave
- SQL thread is stopping, or relay log has a missing tail etc). So we close
- all thread's tables. And so the table mappings have to be cancelled.
- 2) Rows_log_event::exec_event() may even have started statements or
- transactions on them, which we need to rollback in case of error.
- 3) If finding a Format_description_log_event after a BEGIN, we also need
- to rollback before continuing with the next events.
- 4) so we need this "context cleanup" function.
- */
- if (error)
- {
- ha_autocommit_or_rollback(thd, 1); // if a "statement transaction"
- end_trans(thd, ROLLBACK); // if a "real transaction"
- }
- m_table_map.clear_tables();
- close_thread_tables(thd);
- clear_tables_to_lock();
- unsafe_to_stop_at= 0;
- DBUG_VOID_RETURN;
-}
-#endif
-
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
template class I_List_iterator<i_string>;