List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:December 3 2009 8:08pm
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"
      Warning: this patch contains an incompatible change. 
      When waiting on a lock in thr_lock.c, the server used to display "Locked"
      processlist state. After this patch, the state is "Table lock".
      The new state was actually intended to be display since year 2002,
      when Monty added it. But up until removal of thd->locked boolean
      member, this state was ignored by SHOW PROCESSLIST code.  
     @ 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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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 20:08: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-20091203200827-nwrw6lpatzf115q0.bundle
Thread
bzr commit into mysql-5.6-next-mr branch (kostja:2985) Bug#39897Konstantin Osipov3 Dec