summaryrefslogtreecommitdiff
path: root/mysql-test/extra/rpl_tests
diff options
context:
space:
mode:
authorDavi Arnaut <davi.arnaut@oracle.com>2010-10-13 22:54:07 -0300
committerDavi Arnaut <davi.arnaut@oracle.com>2010-10-13 22:54:07 -0300
commit7d64c364865599b14f4b30f42a7ffcd1c7e1557c (patch)
tree02562c5da2ece30266b87c60cbfcdd8d5d3ef88b /mysql-test/extra/rpl_tests
parentdab7abbed8869b7c3a96e75b7bb52944ac58fef1 (diff)
downloadmariadb-git-7d64c364865599b14f4b30f42a7ffcd1c7e1557c.tar.gz
Bug#56096: STOP SLAVE hangs if executed in parallel with user sleep
The root of the problem is that to interrupt a slave SQL thread wait, the STOP SLAVE implementation uses thd->awake(THD::NOT_KILLED). This appears as a spurious wakeup (e.g. from a sleep on a condition variable) to the code that the slave SQL thread is executing at the time of the STOP. If the code is not written to be spurious-wakeup safe, unexpected behavior can occur. For the reported case, this problem led to an infinite loop around the interruptible_wait() function in item_func.cc (SLEEP() function implementation). The loop was not being properly restarted and, consequently, would not come to an end. Since the SLEEP function sleeps on a timed event in order to be killable and to perform periodic checks until the requested time has elapsed, the spurious wake up was causing the requested sleep time to be reset every two seconds. The solution is to calculate the requested absolute time only once and to ensure that the thread only sleeps until this time is elapsed. In case of a spurious wake up, the sleep is restarted using the previously calculated absolute time. This restores the behavior present in previous releases. If a slave thread is executing a SLEEP function, a STOP SLAVE statement will wait until the time requested in the sleep function has elapsed.
Diffstat (limited to 'mysql-test/extra/rpl_tests')
-rw-r--r--mysql-test/extra/rpl_tests/rpl_start_stop_slave.test56
1 files changed, 56 insertions, 0 deletions
diff --git a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test
index 05836737717..5c99fa1bc74 100644
--- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test
+++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test
@@ -122,4 +122,60 @@ drop table t1i, t2m;
sync_slave_with_master;
+--echo #
+--echo # Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep
+--echo #
+
+--connection master
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (a INT );
+
+sync_slave_with_master;
+
+--connection slave1
+--echo # Slave1: lock table for synchronization
+LOCK TABLES t1 WRITE;
+
+--connection master
+--echo # Master: insert into the table
+INSERT INTO t1 SELECT SLEEP(4);
+
+--connection slave
+--echo # Slave: wait for the insert
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE STATE = "Waiting for table metadata lock"
+ AND INFO = "INSERT INTO t1 SELECT SLEEP(4)";
+--source include/wait_condition.inc
+
+--echo # Slave: send slave stop
+--send STOP SLAVE
+
+--connection slave1
+--echo # Slave1: wait for stop slave
+let $wait_condition=
+ SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+ WHERE INFO = "STOP SLAVE";
+--source include/wait_condition.inc
+
+--echo # Slave1: unlock the table
+UNLOCK TABLES;
+
+--connection slave
+--echo # Slave: wait for the slave to stop
+--reap
+--source include/wait_for_slave_to_stop.inc
+
+--echo # Start slave again
+--source include/start_slave.inc
+
+--echo # Clean up
+--connection master
+DROP TABLE t1;
+sync_slave_with_master;
+
# End of tests