diff options
author | unknown <monty@narttu.mysql.fi> | 2003-03-19 22:25:44 +0200 |
---|---|---|
committer | unknown <monty@narttu.mysql.fi> | 2003-03-19 22:25:44 +0200 |
commit | 161942e3cefd8923633e0a7b3b7a9860a95f6fbc (patch) | |
tree | abbee7d78d1399086c301a5bd02f3ba4a9e1ea38 /sql/slave.cc | |
parent | d7bedeb998c911c921d7b67dc07049955481d9b7 (diff) | |
parent | 7517a59a6dac4580b1f7b5cf87abf6d75b096bbc (diff) | |
download | mariadb-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.cc | 60 |
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; } /* |