diff options
author | Seppo Jaakola <seppo.jaakola@codership.com> | 2012-04-26 13:59:35 +0300 |
---|---|---|
committer | Seppo Jaakola <seppo.jaakola@codership.com> | 2012-04-26 13:59:35 +0300 |
commit | e0015163515d1fe5d3747c6f859461a30c2ecfd6 (patch) | |
tree | e8602e5ae53ae2cef06322a338205b501efe8d2a /sql/slave.cc | |
parent | f96fd3f40f37c0080e71e45f85e53bd156aa27f5 (diff) | |
parent | b6ad03cde9367e4fae45f8d84d8175599fab61e9 (diff) | |
download | mariadb-git-e0015163515d1fe5d3747c6f859461a30c2ecfd6.tar.gz |
Merge with mariaDB 5.5.23: bzr merge lp:maria/5.5
Diffstat (limited to 'sql/slave.cc')
-rw-r--r-- | sql/slave.cc | 106 |
1 files changed, 90 insertions, 16 deletions
diff --git a/sql/slave.cc b/sql/slave.cc index 833820203b0..ee48b2008dc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2008, 2011, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1342,7 +1342,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi) const char act[]= "now " "wait_for signal.get_unix_timestamp"; - DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(debug_sync_service); DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act))); };); @@ -1392,7 +1392,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi) const char act[]= "now " "wait_for signal.get_server_id"; - DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(debug_sync_service); DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act))); };); @@ -1791,6 +1791,54 @@ Waiting for the slave SQL thread to free enough relay log space"); !(slave_killed=io_slave_killed(thd,mi)) && !rli->ignore_log_space_limit) mysql_cond_wait(&rli->log_space_cond, &rli->log_space_lock); + + /* + Makes the IO thread read only one event at a time + until the SQL thread is able to purge the relay + logs, freeing some space. + + Therefore, once the SQL thread processes this next + event, it goes to sleep (no more events in the queue), + sets ignore_log_space_limit=true and wakes the IO thread. + However, this event may have been enough already for + the SQL thread to purge some log files, freeing + rli->log_space_total . + + This guarantees that the SQL and IO thread move + forward only one event at a time (to avoid deadlocks), + when the relay space limit is reached. It also + guarantees that when the SQL thread is prepared to + rotate (to be able to purge some logs), the IO thread + will know about it and will rotate. + + NOTE: The ignore_log_space_limit is only set when the SQL + thread sleeps waiting for events. + + */ + if (rli->ignore_log_space_limit) + { +#ifndef DBUG_OFF + { + char llbuf1[22], llbuf2[22]; + DBUG_PRINT("info", ("log_space_limit=%s " + "log_space_total=%s " + "ignore_log_space_limit=%d " + "sql_force_rotate_relay=%d", + llstr(rli->log_space_limit,llbuf1), + llstr(rli->log_space_total,llbuf2), + (int) rli->ignore_log_space_limit, + (int) rli->sql_force_rotate_relay)); + } +#endif + if (rli->sql_force_rotate_relay) + { + rotate_relay_log(rli->mi); + rli->sql_force_rotate_relay= false; + } + + rli->ignore_log_space_limit= false; + } + thd->exit_cond(save_proc_info); DBUG_RETURN(slave_killed); } @@ -3037,7 +3085,7 @@ connected: const char act[]= "now " "wait_for signal.io_thread_let_running"; - DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(debug_sync_service); DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act))); };); @@ -4115,8 +4163,8 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) { int error= 0; String error_msg; - ulong inc_pos; - ulong event_pos; + ulonglong inc_pos; + ulonglong event_pos; Relay_log_info *rli= &mi->rli; mysql_mutex_t *log_lock= rli->relay_log.get_log_lock(); ulong s_id; @@ -5066,19 +5114,45 @@ static Log_event* next_event(Relay_log_info* rli) 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 + and reads one more event and starts honoring log_space_limit again. + + If the SQL thread needs more events to be able to rotate the log (it + might need to finish the current group first), then it can ask for one + more at a time. Thus we don't outgrow the relay log indefinitely, + but rather in a controlled manner, until the next rotate. + + When the SQL thread starts it sets ignore_log_space_limit to false. + 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 the SQL thread sets ignore_log_space_limit to 0 when it stops. */ mysql_mutex_lock(&rli->log_space_lock); - // prevent the I/O thread from blocking next times - rli->ignore_log_space_limit= 1; + + /* + If we have reached the limit of the relay space and we + are going to sleep, waiting for more events: + + 1. If outside a group, SQL thread asks the IO thread + to force a rotation so that the SQL thread purges + logs next time it processes an event (thus space is + freed). + + 2. If in a group, SQL thread asks the IO thread to + ignore the limit and queues yet one more event + so that the SQL thread finishes the group and + is are able to rotate and purge sometime soon. + */ + if (rli->log_space_limit && + rli->log_space_limit < rli->log_space_total) + { + /* force rotation if not in an unfinished group */ + rli->sql_force_rotate_relay= !rli->is_in_group(); + + /* ask for one more event */ + rli->ignore_log_space_limit= true; + } + /* If the I/O thread is blocked, unblock it. Ok to broadcast after unlock, because the mutex is only destroyed in |