Commit 80edc81e authored by guilhem@mysql.com's avatar guilhem@mysql.com

Simplified a test.

thd->enter_cond() and exit_cond(), so that the I/O thread accepts to stop
when it's waiting for relay log space.
Reset ignore_log_space_limit to 0 when the SQL thread terminates.
parent 2e8cb7c3
...@@ -6,8 +6,14 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; ...@@ -6,8 +6,14 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start; slave start;
stop slave; stop slave;
create table t1 (a int); create table t1 (a int);
drop table t1;
create table t1 (a int);
drop table t1;
reset slave;
start slave io_thread;
stop slave io_thread;
reset slave; reset slave;
start slave; start slave;
select master_pos_wait('master-bin.001',5000,45)=-1; select master_pos_wait('master-bin.001',200,6)=-1;
master_pos_wait('master-bin.001',5000,45)=-1 master_pos_wait('master-bin.001',200,6)=-1
0 0
-O relay_log_space_limit=1024 -O relay_log_space_limit=10
\ No newline at end of file \ No newline at end of file
# The slave is started with relay_log_space_limit=1024 bytes, # The slave is started with relay_log_space_limit=10 bytes,
# to force the deadlock # to force the deadlock after one event.
source include/master-slave.inc; source include/master-slave.inc;
connection slave; connection slave;
stop slave; stop slave;
connection master; connection master;
# This will generate a master's binlog > 10 bytes
create table t1 (a int); create table t1 (a int);
let $1=200; drop table t1;
disable_query_log; create table t1 (a int);
while ($1) drop table t1;
{
# eval means expand $ expressions
eval insert into t1 values( $1 );
dec $1;
}
# This will generate one 10kB master's binlog
enable_query_log;
save_master_pos;
connection slave; connection slave;
reset slave; reset slave;
start slave io_thread;
# Give the I/O thread time to block.
sleep 2;
# A bug caused the I/O thread to refuse stopping.
stop slave io_thread;
reset slave;
start slave; start slave;
# The I/O thread stops filling the relay log when # The I/O thread stops filling the relay log when
# it's 1kB. And the SQL thread cannot purge this relay log # it's >10b. And the SQL thread cannot purge this relay log
# as purge is done only when the SQL thread switches to another # as purge is done only when the SQL thread switches to another
# relay log, which does not exist here. # relay log, which does not exist here.
# So we should have a deadlock. # So we should have a deadlock.
# if it is not resolved automatically we'll detect # if it is not resolved automatically we'll detect
# it with master_pos_wait that waits for farther than 1kB; # it with master_pos_wait that waits for farther than 1Ob;
# it will timeout after 45 seconds; # it will timeout after 10 seconds;
# also the slave will probably not cooperate to shutdown # also the slave will probably not cooperate to shutdown
# (as 2 threads are locked) # (as 2 threads are locked)
select master_pos_wait('master-bin.001',5000,45)=-1; select master_pos_wait('master-bin.001',200,6)=-1;
...@@ -1392,18 +1392,18 @@ static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli) ...@@ -1392,18 +1392,18 @@ static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli)
{ {
bool slave_killed=0; bool slave_killed=0;
MASTER_INFO* mi = rli->mi; MASTER_INFO* mi = rli->mi;
const char* save_proc_info;
THD* thd = mi->io_thd; THD* thd = mi->io_thd;
DBUG_ENTER("wait_for_relay_log_space"); DBUG_ENTER("wait_for_relay_log_space");
pthread_mutex_lock(&rli->log_space_lock); pthread_mutex_lock(&rli->log_space_lock);
save_proc_info = thd->proc_info; const char* save_proc_info= thd->enter_cond(&rli->log_space_cond,
thd->proc_info = "Waiting for relay log space to free"; &rli->log_space_lock,
"Waiting for relay log space to free");
while (rli->log_space_limit < rli->log_space_total && 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) !rli->ignore_log_space_limit)
pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock); pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
thd->proc_info = save_proc_info; thd->exit_cond(save_proc_info);
pthread_mutex_unlock(&rli->log_space_lock); pthread_mutex_unlock(&rli->log_space_lock);
DBUG_RETURN(slave_killed); DBUG_RETURN(slave_killed);
} }
...@@ -2445,6 +2445,8 @@ reconnect done to recover from failed read"); ...@@ -2445,6 +2445,8 @@ reconnect done to recover from failed read");
for no reason, but this function will do a clean read, notice the clean for no reason, but this function will do a clean read, notice the clean
value and exit immediately. value and exit immediately.
*/ */
DBUG_PRINT("info", ("ignore_log_space_limit=%d", (int)
mi->rli.ignore_log_space_limit));
if (mi->rli.log_space_limit && mi->rli.log_space_limit < 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) !mi->rli.ignore_log_space_limit)
...@@ -2626,6 +2628,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ ...@@ -2626,6 +2628,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
pthread_mutex_unlock(&rli->data_lock); pthread_mutex_unlock(&rli->data_lock);
DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions")); DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
pthread_cond_broadcast(&rli->data_cond); pthread_cond_broadcast(&rli->data_cond);
rli->ignore_log_space_limit= 0; /* don't need any lock */
rli->save_temporary_tables = thd->temporary_tables; rli->save_temporary_tables = thd->temporary_tables;
/* /*
...@@ -3268,8 +3271,8 @@ Log_event* next_event(RELAY_LOG_INFO* rli) ...@@ -3268,8 +3271,8 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
log), and also when the SQL thread starts. We should also reset 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 ignore_log_space_limit to 0 when the user does RESET SLAVE, but in
fact, no need as RESET SLAVE requires that the slave fact, no need as RESET SLAVE requires that the slave
be stopped, and when the SQL thread is later restarted be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
ignore_log_space_limit will be reset to 0. it stops.
*/ */
pthread_mutex_lock(&rli->log_space_lock); pthread_mutex_lock(&rli->log_space_lock);
// prevent the I/O thread from blocking next times // prevent the I/O thread from blocking next times
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment