diff --git a/sql/rpl_slave.cc b/sql/rpl_slave.cc index a32a1ef..8fff0f2 100644 --- a/sql/rpl_slave.cc +++ b/sql/rpl_slave.cc @@ -9826,11 +9826,17 @@ static Log_event* next_event(Relay_log_info* rli) set_timespec_nsec(&waittime, period); ret= rli->relay_log.wait_for_update_relay_log(thd, &waittime); } while ((ret == ETIMEDOUT || ret == ETIME) /* todo:remove */ && - signal_cnt == rli->relay_log.signal_cnt && !thd->killed); + signal_cnt == rli->relay_log.signal_cnt && + !sql_slave_killed(thd, rli)); } else { - rli->relay_log.wait_for_update_relay_log(thd, NULL); + struct timespec waittime; + set_timespec_nsec(&waittime, rpl_stop_slave_timeout); + while (!sql_slave_killed(thd, rli)) + { + rli->relay_log.wait_for_update_relay_log(thd, &waittime); + } } // re-acquire data lock since we released it earlier diff --git a/sql/rpl_slave_commit_order_manager.cc b/sql/rpl_slave_commit_order_manager.cc index 518ee9f..8b072fb 100644 --- a/sql/rpl_slave_commit_order_manager.cc +++ b/sql/rpl_slave_commit_order_manager.cc @@ -17,6 +17,8 @@ #include "rpl_rli_pdb.h" // Slave_worker +uint slave_commit_order_wait_nsecs = 3; + Commit_order_manager::Commit_order_manager(uint32 worker_numbers) : m_rollback_trx(false), m_workers(worker_numbers), queue_head(QUEUE_EOF), queue_tail(QUEUE_EOF) @@ -70,7 +72,7 @@ bool Commit_order_manager::wait_for_its_turn(Slave_worker *worker, thd->ENTER_COND(cond, &m_mutex, &stage_worker_waiting_for_its_turn_to_commit, &old_stage); - + struct timespec abstime; while (queue_front() != worker->id) { if (unlikely(worker->found_order_commit_deadlock())) @@ -79,7 +81,19 @@ bool Commit_order_manager::wait_for_its_turn(Slave_worker *worker, thd->EXIT_COND(&old_stage); DBUG_RETURN(true); } - mysql_cond_wait(cond, &m_mutex); + set_timespec(&abstime, slave_commit_order_wait_nsecs); + if (ETIMEDOUT == mysql_cond_timedwait(cond, &m_mutex, &abstime)) + { + if (abort_loop || thd->killed || worker->abort_slave || + (worker->c_rli && worker->c_rli->abort_slave)) + { + // Slave worker is committing transaction out of order because 'stop slave' was executed. + mysql_mutex_unlock(&m_mutex); + thd->EXIT_COND(&old_stage); + m_workers[worker->id].status= OCS_SIGNAL; // signal anyway. + DBUG_RETURN(false); + } + } } mysql_mutex_unlock(&m_mutex); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index d70ebef..bff395a 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -969,6 +969,13 @@ static Sys_var_ulonglong Sys_select_rows_limit( VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1)); +extern uint slave_commit_order_wait_nsecs; +static Sys_var_uint Sys_slave_commit_order_wait_nsecs( + "slave_commit_order_wait_nsecs", + "Number of seconds slave worker thread wait for commit order before it checks slave stopped.", + GLOBAL_VAR(slave_commit_order_wait_nsecs), CMD_LINE(OPT_ARG), + VALID_RANGE(1, UINT_MAX), DEFAULT(3), BLOCK_SIZE(1)); + my_bool forbid_server_path_remote_access= false; static Sys_var_mybool Sys_forbid_server_path_remote_access( "forbid_server_path_remote_access",