List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:December 3 2009 7:31pm
Subject:bzr commit into mysql-5.6-next-mr branch (kostja:2985) Bug#39897
View as plain text  
#At file:///opt/local/work/next-4284/ based on revid:kostja@stripped

 2985 Konstantin Osipov	2009-12-03
      Backport of:
      ------------------------------------------------------------
      revno: 3035.4.1
      committer: Davi Arnaut <Davi.Arnaut@stripped>
      branch nick: 39897-6.0
      timestamp: Thu 2009-01-15 12:17:57 -0200
      message:
      Bug#39897: lock_multi fails in pushbuild: timeout waiting for processlist
      
      The problem is that relying on the "Table lock" thread state in
      its current position to detect that a thread is waiting on a lock
      is race prone. The "Table lock" state change happens before the
      thread actually tries to grab a lock on a table.
      
      The solution is to move the "Table lock" state so that its set
      only when a thread is actually going to wait for a lock. The state
      change happens after the thread fails to grab the lock (because it
      is owned by other thread) and proceeds to wait on a condition.
      
      This is considered part of work related to WL#4284 "Transactional
      DDL locking"
     @ mysql-test/r/lock_multi.result
        A style fix.
     @ mysql-test/r/sp-threads.result
        Changed output of SHOW PROCESSLIST (new wait state).
     @ mysql-test/t/lock_multi.test
        Use a more accurate state description when waiting inside thr_lock.c.
     @ mysql-test/t/lock_sync.test
        Use a more accurate state description when waiting inside thr_lock.c.
     @ mysql-test/t/multi_update.test
        Use a more accurate state description when waiting inside thr_lock.c.
     @ mysql-test/t/query_cache_28249.test
        Use a more accurate state description when waiting inside thr_lock.c.
     @ mysql-test/t/sp_notembedded.test
        Use a more accurate state description when waiting inside thr_lock.c.
     @ mysql-test/t/status.test
        Use a more accurate state description when waiting inside thr_lock.c.
     @ mysys/thr_lock.c
        Update thread state while waiting for a table lock.
     @ sql/lock.cc
        State change was moved inside thr_lock.c.

    modified:
      mysql-test/r/lock_multi.result
      mysql-test/r/sp-threads.result
      mysql-test/t/delayed.test
      mysql-test/t/insert_notembedded.test
      mysql-test/t/lock_multi.test
      mysql-test/t/lock_sync.test
      mysql-test/t/multi_update.test
      mysql-test/t/query_cache_28249.test
      mysql-test/t/sp_notembedded.test
      mysql-test/t/status.test
      mysys/thr_lock.c
      sql/lock.cc
=== modified file 'mysql-test/r/lock_multi.result'
--- a/mysql-test/r/lock_multi.result	2009-11-20 20:12:57 +0000
+++ b/mysql-test/r/lock_multi.result	2009-12-03 19:31:27 +0000
@@ -203,7 +203,7 @@ drop table if exists t1,t2;
 create table t1 (a int);
 flush status;
 lock tables t1 read;
-insert into t1 values(1);;
+insert into t1 values(1);
 unlock tables;
 drop table t1;
 select @tlwa < @tlwb;

=== modified file 'mysql-test/r/sp-threads.result'
--- a/mysql-test/r/sp-threads.result	2006-10-04 14:35:40 +0000
+++ b/mysql-test/r/sp-threads.result	2009-12-03 19:31:27 +0000
@@ -35,7 +35,7 @@ call bug9486();
 show processlist;
 Id	User	Host	db	Command	Time	State	Info
 #	root	localhost	test	Sleep	#		NULL
-#	root	localhost	test	Query	#	Locked	update t1, t2 set val= 1 where id1=id2
+#	root	localhost	test	Query	#	Table lock	update t1, t2 set val= 1 where id1=id2
 #	root	localhost	test	Query	#	NULL	show processlist
 #	root	localhost	test	Sleep	#		NULL
 unlock tables;

=== modified file 'mysql-test/t/delayed.test'
--- a/mysql-test/t/delayed.test	2009-11-02 11:10:04 +0000
+++ b/mysql-test/t/delayed.test	2009-12-03 19:31:27 +0000
@@ -307,7 +307,7 @@ connection update;
 connection default;
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where command = "Delayed insert" and state = "upgrading lock";
+  where command = "Delayed insert" and state = "Table lock";
 --source include/wait_condition.inc
 connect (select,localhost,root,,);
 --echo connection: select

=== modified file 'mysql-test/t/insert_notembedded.test'
--- a/mysql-test/t/insert_notembedded.test	2009-11-20 19:51:12 +0000
+++ b/mysql-test/t/insert_notembedded.test	2009-12-03 19:31:27 +0000
@@ -174,7 +174,7 @@ connection default;
 # we must wait till the insert opens and locks the table
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and id = $ID;
+  where state = "Table lock" and id = $ID;
 --source include/wait_condition.inc
 connect (select,localhost,root,,);
 --echo connection: select

=== modified file 'mysql-test/t/lock_multi.test'
--- a/mysql-test/t/lock_multi.test	2009-11-30 15:55:03 +0000
+++ b/mysql-test/t/lock_multi.test	2009-12-03 19:31:27 +0000
@@ -22,7 +22,7 @@ connection reader;
 # Sleep a bit till the update of connection writer is in work and hangs
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "update low_priority t1 set n = 4";
+  where state = "Table lock" and info = "update low_priority t1 set n = 4";
 --source include/wait_condition.inc
 send
 select n from t1;
@@ -30,7 +30,7 @@ connection locker;
 # Sleep a bit till the select of connection reader is in work and hangs
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "select n from t1";
+  where state = "Table lock" and info = "select n from t1";
 --source include/wait_condition.inc
 unlock tables;
 connection writer;
@@ -50,7 +50,7 @@ connection reader;
 # Sleep a bit till the update of connection writer is in work and hangs
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "update low_priority t1 set n = 4";
+  where state = "Table lock" and info = "update low_priority t1 set n = 4";
 --source include/wait_condition.inc
 select n from t1;
 connection locker;
@@ -95,7 +95,7 @@ insert t1 select * from t2;
 connection locker;
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "insert t1 select * from t2";
+  where state = "Table lock" and info = "insert t1 select * from t2";
 --source include/wait_condition.inc
 drop table t2;
 connection reader;
@@ -119,7 +119,7 @@ connection locker;
 # Sleep a bit till the insert of connection reader is in work and hangs
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "insert t1 select * from t2";
+  where state = "Table lock" and info = "insert t1 select * from t2";
 --source include/wait_condition.inc
 drop table t2;
 connection reader;
@@ -163,8 +163,8 @@ SELECT user.Select_priv FROM user, db WH
 connection locker;
 # Sleep a bit till the select of connection reader is in work and hangs
 let $wait_condition=
-  select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = 
+  SELECT COUNT(*) = 1 FROM information_schema.processlist
+  WHERE state = "Table lock" AND info =
   "SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1";
 --source include/wait_condition.inc
 # Make test case independent from earlier grants.
@@ -298,7 +298,7 @@ connection reader;
 # Wait till connection writer is blocked
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "alter table t1 auto_increment=0";
+  where state = "Table lock" and info = "alter table t1 auto_increment=0";
 --source include/wait_condition.inc
 send
 alter table t1 auto_increment=0;
@@ -306,7 +306,7 @@ connection locker;
 # Wait till connection reader is blocked
 let $wait_condition=
   select count(*) = 2 from information_schema.processlist
-  where state = "Locked" and info = "alter table t1 auto_increment=0";
+  where state = "Table lock" and info = "alter table t1 auto_increment=0";
 --source include/wait_condition.inc
 unlock tables;
 connection writer;
@@ -461,16 +461,16 @@ update t1 set i= 10;
 connection reader;
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "update t1 set i= 10";
+  where state = "Table lock" and info = "update t1 set i= 10";
 --source include/wait_condition.inc
 send
 select * from t1;
 connection default;
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "select * from t1";
+  where state = "Table lock" and info = "select * from t1";
 --source include/wait_condition.inc
-let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
+let $ID= `select id from information_schema.processlist where state = "Table lock" and info = "update t1 set i= 10"`;
 --replace_result $ID ID
 eval kill query $ID;
 connection reader;
@@ -613,11 +613,11 @@ lock tables t1 read;
 let $tlwa= `show status like 'Table_locks_waited'`;
 connect (waiter,localhost,root,,);
 connection waiter;
---send insert into t1 values(1);
+send insert into t1 values(1);
 connection default;
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and info = "insert into t1 values(1)";
+  where state = "Table lock" and info = "insert into t1 values(1)";
 --source include/wait_condition.inc
 let $tlwb= `show status like 'Table_locks_waited'`;
 unlock tables;

=== modified file 'mysql-test/t/lock_sync.test'
--- a/mysql-test/t/lock_sync.test	2009-10-27 09:43:40 +0000
+++ b/mysql-test/t/lock_sync.test	2009-12-03 19:31:27 +0000
@@ -71,7 +71,7 @@ set debug_sync= 'now WAIT_FOR parked';
 connection default;
 --echo # Wait until this LOCK TABLES statement starts waiting for table lock.
 let $wait_condition= select count(*)= 1 from information_schema.processlist
-                       where state= 'Locked' and
+                       where state= 'Table lock' and
                              info='lock table t1 write';
 --source include/wait_condition.inc
 --echo # Allow SELECT ... FOR UPDATE to resume.

=== modified file 'mysql-test/t/multi_update.test'
--- a/mysql-test/t/multi_update.test	2009-02-09 21:00:15 +0000
+++ b/mysql-test/t/multi_update.test	2009-12-03 19:31:27 +0000
@@ -496,7 +496,7 @@ connection updater;
 # Wait till "alter table t1 ..." of session changer is in work.
 # = There is one session is in state "Locked".
 let $wait_condition= select count(*)= 1 from information_schema.processlist
-                     where state= 'Locked';
+                     where state= 'Table lock';
 --source include/wait_condition.inc
 send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
 
@@ -507,7 +507,7 @@ connection locker;
 # are in work.
 # = There are two session is in state "Locked".
 let $wait_condition= select count(*)= 2 from information_schema.processlist
-                     where state= 'Locked';
+                     where state= 'Table lock';
 --source include/wait_condition.inc
 unlock tables;
 

=== modified file 'mysql-test/t/query_cache_28249.test'
--- a/mysql-test/t/query_cache_28249.test	2009-02-23 08:03:31 +0000
+++ b/mysql-test/t/query_cache_28249.test	2009-12-03 19:31:27 +0000
@@ -58,18 +58,18 @@ connection user3;
 # Typical information_schema.processlist content after sufficient sleep time
 #   ID  USER  COMMAND  TIME  STATE   INFO
 #   ....
-#   2   root  Query       5  Locked  SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+#   2   root  Query       5  Table lock  SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
 #   ....
 #                            XXXXXX  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 # The values marked with 'X' must be reached.
 --echo # Poll till the select of connection user1 is blocked by the write lock on t1.
 let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = 'Table lock'
   AND info = '$select_for_qc';
 --source include/wait_condition.inc
 eval
 SELECT user,command,state,info FROM information_schema.processlist
-WHERE state = 'Locked'
+WHERE state = 'Table lock'
   AND info = '$select_for_qc';
 INSERT INTO t1 VALUES (4);
 

=== modified file 'mysql-test/t/sp_notembedded.test'
--- a/mysql-test/t/sp_notembedded.test	2009-10-13 18:21:42 +0000
+++ b/mysql-test/t/sp_notembedded.test	2009-12-03 19:31:27 +0000
@@ -322,7 +322,7 @@ set session low_priority_updates=on;
 connection rl_wait;
 let $wait_condition=
   select count(*) = 1 from information_schema.processlist
-  where state = "Locked" and
+  where state = "Table lock" and
   info = "update t1 set value='updated' where value='old'";
 --source include/wait_condition.inc
 

=== modified file 'mysql-test/t/status.test'
--- a/mysql-test/t/status.test	2009-11-20 20:30:00 +0000
+++ b/mysql-test/t/status.test	2009-12-03 19:31:27 +0000
@@ -58,7 +58,7 @@ let $ID= `select connection_id()`;
 connection con2;
 --echo # Switched to connection: con2
 # wait for the other query to start executing
-let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Locked";
+let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Table lock";
 --source include/wait_condition.inc
 unlock tables;
 

=== modified file 'mysys/thr_lock.c'
--- a/mysys/thr_lock.c	2009-12-02 23:09:22 +0000
+++ b/mysys/thr_lock.c	2009-12-03 19:31:27 +0000
@@ -396,6 +396,7 @@ wait_for_lock(struct st_lock_list *wait,
   struct timespec wait_timeout;
   enum enum_thr_lock_result result= THR_LOCK_ABORTED;
   my_bool can_deadlock= test(data->owner->info->n_cursors);
+  const char *old_proc_info;
   DBUG_ENTER("wait_for_lock");
 
   /*
@@ -434,6 +435,9 @@ wait_for_lock(struct st_lock_list *wait,
   thread_var->current_cond=  cond;
   data->cond= cond;
 
+  old_proc_info= proc_info_hook(NULL, "Table lock",
+                                __func__, __FILE__, __LINE__);
+
   if (can_deadlock)
     set_timespec(wait_timeout, table_lock_wait_timeout);
   while (!thread_var->abort || in_wait_list)
@@ -504,6 +508,9 @@ wait_for_lock(struct st_lock_list *wait,
   thread_var->current_mutex= 0;
   thread_var->current_cond=  0;
   pthread_mutex_unlock(&thread_var->mutex);
+
+  proc_info_hook(NULL, old_proc_info, __func__, __FILE__, __LINE__);
+
   DBUG_RETURN(result);
 }
 

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2009-12-02 20:47:23 +0000
+++ b/sql/lock.cc	2009-12-03 19:31:27 +0000
@@ -310,7 +310,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, 
       break;
     }
     DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
-    thd_proc_info(thd, "Locked");
     /* Copy the lock data array. thr_multi_lock() reorders its contens. */
     memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
            sql_lock->lock_count * sizeof(*sql_lock->locks));


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20091203193127-z3cwjmx9ck4to39a.bundle
Thread
bzr commit into mysql-5.6-next-mr branch (kostja:2985) Bug#39897Konstantin Osipov3 Dec