#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#39897 | Konstantin Osipov | 3 Dec |