summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2003-03-19 22:25:44 +0200
committerunknown <monty@narttu.mysql.fi>2003-03-19 22:25:44 +0200
commit161942e3cefd8923633e0a7b3b7a9860a95f6fbc (patch)
treeabbee7d78d1399086c301a5bd02f3ba4a9e1ea38 /sql/slave.cc
parentd7bedeb998c911c921d7b67dc07049955481d9b7 (diff)
parent7517a59a6dac4580b1f7b5cf87abf6d75b096bbc (diff)
downloadmariadb-git-161942e3cefd8923633e0a7b3b7a9860a95f6fbc.tar.gz
Merge with 4.0.12
Docs/internals.texi: Auto merged include/my_global.h: Auto merged include/mysql_com.h: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged libmysql/Makefile.am: Auto merged libmysqld/Makefile.am: Auto merged libmysqld/lib_vio.c: Auto merged mysql-test/r/heap.result: Auto merged mysql-test/r/innodb.result: Auto merged mysql-test/t/heap.test: Auto merged sql/ha_innodb.h: Auto merged sql/ha_myisam.cc: Auto merged BitKeeper/deleted/.del-password.c~76f30876e68eddb4: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item_func.cc: Auto merged sql/key.cc: Auto merged sql/lex.h: Auto merged sql/log.cc: Auto merged sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/slave.h: Auto merged sql/sql_class.cc: Auto merged sql/sql_repl.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.cc: Auto merged strings/strto.c: Auto merged
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc60
1 files changed, 51 insertions, 9 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index 61348722d1e..c66f5c307d4 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -263,7 +263,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
if (log) // If not first log
{
if (strcmp(log, rli->linfo.log_file_name))
- rli->skip_log_purge=1; // Different name; Don't purge
+ rli->skip_log_purge= 1; // Different name; Don't purge
if (rli->relay_log.find_log_pos(&rli->linfo, log, 1))
{
*errmsg="Could not find target log during relay log initialization";
@@ -298,6 +298,12 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,
my_b_seek(rli->cur_log,(off_t)pos);
err:
+ /*
+ If we don't purge, we can't honour relay_log_space_limit ;
+ silently discard it
+ */
+ if (rli->skip_log_purge)
+ rli->log_space_limit= 0;
pthread_cond_broadcast(&rli->data_cond);
if (need_data_lock)
pthread_mutex_unlock(&rli->data_lock);
@@ -1386,7 +1392,8 @@ static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli)
thd->proc_info = "Waiting for relay log space to free";
while (rli->log_space_limit < rli->log_space_total &&
- !(slave_killed=io_slave_killed(thd,mi)))
+ !(slave_killed=io_slave_killed(thd,mi)) &&
+ !rli->ignore_log_space_limit)
{
pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
}
@@ -1667,7 +1674,7 @@ bool flush_master_info(MASTER_INFO* mi)
st_relay_log_info::st_relay_log_info()
:info_fd(-1), cur_log_fd(-1), master_log_pos(0), save_temporary_tables(0),
- cur_log_old_open_count(0), log_space_total(0),
+ cur_log_old_open_count(0), log_space_total(0), ignore_log_space_limit(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), skip_log_purge(0),
@@ -2378,7 +2385,8 @@ reconnect done to recover from failed read");
}
flush_master_info(mi);
if (mi->rli.log_space_limit && mi->rli.log_space_limit <
- mi->rli.log_space_total)
+ mi->rli.log_space_total &&
+ !mi->rli.ignore_log_space_limit)
if (wait_for_relay_log_space(&mi->rli))
{
sql_print_error("Slave I/O thread aborted while waiting for relay \
@@ -2491,6 +2499,10 @@ slave_begin:
pthread_cond_broadcast(&rli->start_cond);
// This should always be set to 0 when the slave thread is started
rli->pending = 0;
+
+ //tell the I/O thread to take relay_log_space_limit into account from now on
+ rli->ignore_log_space_limit= 0;
+
if (init_relay_log_pos(rli,
rli->relay_log_name,
rli->relay_log_pos,
@@ -3199,11 +3211,41 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
update. If we do not, show slave status will block
*/
pthread_mutex_unlock(&rli->data_lock);
- /* Note that wait_for_update unlocks lock_log ! */
- rli->relay_log.wait_for_update(rli->sql_thd);
-
- // re-acquire data lock since we released it earlier
- pthread_mutex_lock(&rli->data_lock);
+
+ /*
+ Possible deadlock :
+ - the I/O thread has reached log_space_limit
+ - the SQL thread has read all relay logs, but cannot purge for some
+ reason:
+ * it has already purged all logs except the current one
+ * there are other logs than the current one but they're involved in
+ a transaction that finishes in the current one (or is not finished)
+ Solution :
+ Wake up the possibly waiting I/O thread, and set a boolean asking
+ the I/O thread to temporarily ignore the log_space_limit
+ constraint, because we do not want the I/O thread to block because of
+ space (it's ok if it blocks for any other reason (e.g. because the
+ master does not send anything). Then the I/O thread stops waiting
+ and reads more events.
+ The SQL thread decides when the I/O thread should take log_space_limit
+ into account again : ignore_log_space_limit is reset to 0
+ in purge_first_log (when the SQL thread purges the just-read relay
+ log), and also when the SQL thread starts. We should also reset
+ ignore_log_space_limit to 0 when the user does RESET SLAVE, but in
+ fact, no need as RESET SLAVE requires that the slave
+ be stopped, and when the SQL thread is later restarted
+ ignore_log_space_limit will be reset to 0.
+ */
+ pthread_mutex_lock(&rli->log_space_lock);
+ // prevent the I/O thread from blocking next times
+ rli->ignore_log_space_limit= 1;
+ // If the I/O thread is blocked, unblock it
+ pthread_cond_broadcast(&rli->log_space_cond);
+ pthread_mutex_unlock(&rli->log_space_lock);
+ // Note that wait_for_update unlocks lock_log !
+ rli->relay_log.wait_for_update(rli->sql_thd);
+ // re-acquire data lock since we released it earlier
+ pthread_mutex_lock(&rli->data_lock);
continue;
}
/*