From: Alexander Nozdrin Date: October 14 2010 10:12am Subject: bzr push into mysql-trunk-merge branch (alexander.nozdrin:3269 to 3270) List-Archive: http://lists.mysql.com/commits/120767 Message-Id: <201010141013.o9DG1U4R024487@rcsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8341126107493341277==" --===============8341126107493341277== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 3270 Alexander Nozdrin 2010-10-14 [merge] Auto-merge from mysql-5.5-bugteam. modified: mysql-test/extra/rpl_tests/rpl_start_stop_slave.test mysql-test/include/mtr_warnings.sql mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result sql/item_func.cc 3269 Alexander Nozdrin 2010-10-13 [merge] Auto-merge from mysql-5.5-bugteam. === modified file 'mysql-test/extra/rpl_tests/rpl_start_stop_slave.test' --- a/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test 2010-04-28 12:47:49 +0000 +++ b/mysql-test/extra/rpl_tests/rpl_start_stop_slave.test 2010-10-14 01:54:07 +0000 @@ -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 === modified file 'mysql-test/include/mtr_warnings.sql' --- a/mysql-test/include/mtr_warnings.sql 2010-08-04 12:38:29 +0000 +++ b/mysql-test/include/mtr_warnings.sql 2010-10-14 10:12:00 +0000 @@ -16,6 +16,12 @@ CREATE TABLE test_suppressions ( -- no invalid patterns can be inserted -- into test_suppressions -- +SET @character_set_client_saved = @@character_set_client|| +SET @character_set_results_saved = @@character_set_results|| +SET @collation_connection_saved = @@collation_connection|| +SET @@character_set_client = latin1|| +SET @@character_set_results = latin1|| +SET @@collation_connection = latin1_swedish_ci|| /*!50002 CREATE DEFINER=root@localhost TRIGGER ts_insert BEFORE INSERT ON test_suppressions @@ -24,6 +30,9 @@ FOR EACH ROW BEGIN SELECT "" REGEXP NEW.pattern INTO dummy; END */|| +SET @@character_set_client = @character_set_client_saved|| +SET @@character_set_results = @character_set_results_saved|| +SET @@collation_connection = @collation_connection_saved|| -- @@ -38,6 +47,12 @@ CREATE TABLE global_suppressions ( -- no invalid patterns can be inserted -- into global_suppressions -- +SET @character_set_client_saved = @@character_set_client|| +SET @character_set_results_saved = @@character_set_results|| +SET @collation_connection_saved = @@collation_connection|| +SET @@character_set_client = latin1|| +SET @@character_set_results = latin1|| +SET @@collation_connection = latin1_swedish_ci|| /*!50002 CREATE DEFINER=root@localhost TRIGGER gs_insert BEFORE INSERT ON global_suppressions @@ -46,6 +61,9 @@ FOR EACH ROW BEGIN SELECT "" REGEXP NEW.pattern INTO dummy; END */|| +SET @@character_set_client = @character_set_client_saved|| +SET @@character_set_results = @character_set_results_saved|| +SET @@collation_connection = @collation_connection_saved|| === modified file 'mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result' --- a/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result 2010-04-29 11:20:36 +0000 +++ b/mysql-test/suite/rpl/r/rpl_stm_start_stop_slave.result 2010-10-14 10:12:00 +0000 @@ -43,3 +43,25 @@ one 1 include/start_slave.inc drop table t1i, t2m; +# +# Bug#56096 STOP SLAVE hangs if executed in parallel with user sleep +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (a INT ); +# Slave1: lock table for synchronization +LOCK TABLES t1 WRITE; +# Master: insert into the table +INSERT INTO t1 SELECT SLEEP(4); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. +# Slave: wait for the insert +# Slave: send slave stop +STOP SLAVE; +# Slave1: wait for stop slave +# Slave1: unlock the table +UNLOCK TABLES; +# Slave: wait for the slave to stop +# Start slave again +include/start_slave.inc +# Clean up +DROP TABLE t1; === modified file 'sql/item_func.cc' --- a/sql/item_func.cc 2010-10-05 14:35:03 +0000 +++ b/sql/item_func.cc 2010-10-14 10:12:00 +0000 @@ -3691,48 +3691,92 @@ longlong Item_master_pos_wait::val_int() } +/** + Enables a session to wait on a condition until a timeout or a network + disconnect occurs. + + @remark The connection is polled every m_interrupt_interval nanoseconds. +*/ + +class Interruptible_wait +{ + THD *m_thd; + struct timespec m_abs_timeout; + static const ulonglong m_interrupt_interval; + + public: + Interruptible_wait(THD *thd) + : m_thd(thd) {} + + ~Interruptible_wait() {} + + public: + /** + Set the absolute timeout. + + @param timeout The amount of time in nanoseconds to wait + */ + void set_timeout(ulonglong timeout) + { + /* + Calculate the absolute system time at the start so it can + be controlled in slices. It relies on the fact that once + the absolute time passes, the timed wait call will fail + automatically with a timeout error. + */ + set_timespec_nsec(m_abs_timeout, timeout); + } + + /** The timed wait. */ + int wait(mysql_cond_t *, mysql_mutex_t *); +}; + + +/** Time to wait before polling the connection status. */ +const ulonglong Interruptible_wait::m_interrupt_interval= 5 * ULL(1000000000); + /** - Wait for a given condition to be signaled within the specified timeout. + Wait for a given condition to be signaled. + + @param cond The condition variable to wait on. + @param mutex The associated mutex. - @param cond the condition variable to wait on - @param lock the associated mutex - @param abstime the amount of time in seconds to wait + @remark The absolute timeout is preserved across calls. @retval return value from mysql_cond_timedwait */ -#define INTERRUPT_INTERVAL (5 * ULL(1000000000)) - -static int interruptible_wait(THD *thd, mysql_cond_t *cond, - mysql_mutex_t *lock, double time) +int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex) { int error; - struct timespec abstime; - ulonglong slice, timeout= (ulonglong) (time * 1000000000.0); + struct timespec timeout; - do + while (1) { /* Wait for a fixed interval. */ - if (timeout > INTERRUPT_INTERVAL) - slice= INTERRUPT_INTERVAL; - else - slice= timeout; + set_timespec_nsec(timeout, m_interrupt_interval); + + /* But only if not past the absolute timeout. */ + if (cmp_timespec(timeout, m_abs_timeout) > 0) + timeout= m_abs_timeout; - timeout-= slice; - set_timespec_nsec(abstime, slice); - error= mysql_cond_timedwait(cond, lock, &abstime); + error= mysql_cond_timedwait(cond, mutex, &timeout); if (error == ETIMEDOUT || error == ETIME) { /* Return error if timed out or connection is broken. */ - if (!timeout || !thd->is_connected()) + if (!cmp_timespec(timeout, m_abs_timeout) || !m_thd->is_connected()) break; } - } while (error && timeout); + /* Otherwise, propagate status to the caller. */ + else + break; + } return error; } + /** Get a user level lock. If the thread has an old lock this is first released. @@ -3748,10 +3792,11 @@ longlong Item_func_get_lock::val_int() { DBUG_ASSERT(fixed == 1); String *res=args[0]->val_str(&value); - double timeout= args[1]->val_real(); + ulonglong timeout= args[1]->val_int(); THD *thd=current_thd; User_level_lock *ull; int error; + Interruptible_wait timed_cond(thd); DBUG_ENTER("Item_func_get_lock::val_int"); /* @@ -3812,11 +3857,13 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &ull->cond; + timed_cond.set_timeout(timeout * ULL(1000000000)); + error= 0; while (ull->locked && !thd->killed) { DBUG_PRINT("info", ("waiting on lock")); - error= interruptible_wait(thd, &ull->cond, &LOCK_user_locks, timeout); + error= timed_cond.wait(&ull->cond, &LOCK_user_locks); if (error == ETIMEDOUT || error == ETIME) { DBUG_PRINT("info", ("lock wait timeout")); @@ -4011,6 +4058,7 @@ void Item_func_benchmark::print(String * longlong Item_func_sleep::val_int() { THD *thd= current_thd; + Interruptible_wait timed_cond(thd); mysql_cond_t cond; double timeout; int error; @@ -4030,6 +4078,8 @@ longlong Item_func_sleep::val_int() if (timeout < 0.00001) return 0; + timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0)); + mysql_cond_init(key_item_func_sleep_cond, &cond, NULL); mysql_mutex_lock(&LOCK_user_locks); @@ -4040,7 +4090,7 @@ longlong Item_func_sleep::val_int() error= 0; while (!thd->killed) { - error= interruptible_wait(thd, &cond, &LOCK_user_locks, timeout); + error= timed_cond.wait(&cond, &LOCK_user_locks); if (error == ETIMEDOUT || error == ETIME) break; error= 0; --===============8341126107493341277== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/alexander.nozdrin@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alexander.nozdrin@stripped\ # aaz2pstq1af5gn8l # target_branch: file:///home/alik/MySQL/bzr/mysql-trunk-merge/ # testament_sha1: c1f6b39256c60778bb542c7989a4588888ef54cb # timestamp: 2010-10-14 14:12:31 +0400 # source_branch: file:///mnt/raid/alik/MySQL/bzr/mysql-trunk/ # base_revision_id: alexander.nozdrin@stripped\ # ai7dka3mqvqbvwxi # # Begin bundle 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 BkRA --===============8341126107493341277==--