Skip to content

Commit c44665a

Browse files
author
Konstantin Osipov
committed
Backport of:
------------------------------------------------------------ revno: 3035.4.1 committer: Davi Arnaut <Davi.Arnaut@Sun.COM> 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.
1 parent 36897c8 commit c44665a

12 files changed

+33
-27
lines changed

mysql-test/r/lock_multi.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ drop table if exists t1,t2;
203203
create table t1 (a int);
204204
flush status;
205205
lock tables t1 read;
206-
insert into t1 values(1);;
206+
insert into t1 values(1);
207207
unlock tables;
208208
drop table t1;
209209
select @tlwa < @tlwb;

mysql-test/r/sp-threads.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ call bug9486();
3535
show processlist;
3636
Id User Host db Command Time State Info
3737
# root localhost test Sleep # NULL
38-
# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
38+
# root localhost test Query # Table lock update t1, t2 set val= 1 where id1=id2
3939
# root localhost test Query # NULL show processlist
4040
# root localhost test Sleep # NULL
4141
unlock tables;

mysql-test/t/delayed.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ connection update;
307307
connection default;
308308
let $wait_condition=
309309
select count(*) = 1 from information_schema.processlist
310-
where command = "Delayed insert" and state = "upgrading lock";
310+
where command = "Delayed insert" and state = "Table lock";
311311
--source include/wait_condition.inc
312312
connect (select,localhost,root,,);
313313
--echo connection: select

mysql-test/t/insert_notembedded.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ connection default;
174174
# we must wait till the insert opens and locks the table
175175
let $wait_condition=
176176
select count(*) = 1 from information_schema.processlist
177-
where state = "Locked" and id = $ID;
177+
where state = "Table lock" and id = $ID;
178178
--source include/wait_condition.inc
179179
connect (select,localhost,root,,);
180180
--echo connection: select

mysql-test/t/lock_multi.test

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ connection reader;
2222
# Sleep a bit till the update of connection writer is in work and hangs
2323
let $wait_condition=
2424
select count(*) = 1 from information_schema.processlist
25-
where state = "Locked" and info = "update low_priority t1 set n = 4";
25+
where state = "Table lock" and info = "update low_priority t1 set n = 4";
2626
--source include/wait_condition.inc
2727
send
2828
select n from t1;
2929
connection locker;
3030
# Sleep a bit till the select of connection reader is in work and hangs
3131
let $wait_condition=
3232
select count(*) = 1 from information_schema.processlist
33-
where state = "Locked" and info = "select n from t1";
33+
where state = "Table lock" and info = "select n from t1";
3434
--source include/wait_condition.inc
3535
unlock tables;
3636
connection writer;
@@ -50,7 +50,7 @@ connection reader;
5050
# Sleep a bit till the update of connection writer is in work and hangs
5151
let $wait_condition=
5252
select count(*) = 1 from information_schema.processlist
53-
where state = "Locked" and info = "update low_priority t1 set n = 4";
53+
where state = "Table lock" and info = "update low_priority t1 set n = 4";
5454
--source include/wait_condition.inc
5555
select n from t1;
5656
connection locker;
@@ -95,7 +95,7 @@ insert t1 select * from t2;
9595
connection locker;
9696
let $wait_condition=
9797
select count(*) = 1 from information_schema.processlist
98-
where state = "Locked" and info = "insert t1 select * from t2";
98+
where state = "Table lock" and info = "insert t1 select * from t2";
9999
--source include/wait_condition.inc
100100
drop table t2;
101101
connection reader;
@@ -119,7 +119,7 @@ connection locker;
119119
# Sleep a bit till the insert of connection reader is in work and hangs
120120
let $wait_condition=
121121
select count(*) = 1 from information_schema.processlist
122-
where state = "Locked" and info = "insert t1 select * from t2";
122+
where state = "Table lock" and info = "insert t1 select * from t2";
123123
--source include/wait_condition.inc
124124
drop table t2;
125125
connection reader;
@@ -163,8 +163,8 @@ SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1;
163163
connection locker;
164164
# Sleep a bit till the select of connection reader is in work and hangs
165165
let $wait_condition=
166-
select count(*) = 1 from information_schema.processlist
167-
where state = "Locked" and info =
166+
SELECT COUNT(*) = 1 FROM information_schema.processlist
167+
WHERE state = "Table lock" AND info =
168168
"SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1";
169169
--source include/wait_condition.inc
170170
# Make test case independent from earlier grants.
@@ -298,15 +298,15 @@ connection reader;
298298
# Wait till connection writer is blocked
299299
let $wait_condition=
300300
select count(*) = 1 from information_schema.processlist
301-
where state = "Locked" and info = "alter table t1 auto_increment=0";
301+
where state = "Table lock" and info = "alter table t1 auto_increment=0";
302302
--source include/wait_condition.inc
303303
send
304304
alter table t1 auto_increment=0;
305305
connection locker;
306306
# Wait till connection reader is blocked
307307
let $wait_condition=
308308
select count(*) = 2 from information_schema.processlist
309-
where state = "Locked" and info = "alter table t1 auto_increment=0";
309+
where state = "Table lock" and info = "alter table t1 auto_increment=0";
310310
--source include/wait_condition.inc
311311
unlock tables;
312312
connection writer;
@@ -461,16 +461,16 @@ update t1 set i= 10;
461461
connection reader;
462462
let $wait_condition=
463463
select count(*) = 1 from information_schema.processlist
464-
where state = "Locked" and info = "update t1 set i= 10";
464+
where state = "Table lock" and info = "update t1 set i= 10";
465465
--source include/wait_condition.inc
466466
send
467467
select * from t1;
468468
connection default;
469469
let $wait_condition=
470470
select count(*) = 1 from information_schema.processlist
471-
where state = "Locked" and info = "select * from t1";
471+
where state = "Table lock" and info = "select * from t1";
472472
--source include/wait_condition.inc
473-
let $ID= `select id from information_schema.processlist where state = "Locked" and info = "update t1 set i= 10"`;
473+
let $ID= `select id from information_schema.processlist where state = "Table lock" and info = "update t1 set i= 10"`;
474474
--replace_result $ID ID
475475
eval kill query $ID;
476476
connection reader;
@@ -613,11 +613,11 @@ lock tables t1 read;
613613
let $tlwa= `show status like 'Table_locks_waited'`;
614614
connect (waiter,localhost,root,,);
615615
connection waiter;
616-
--send insert into t1 values(1);
616+
send insert into t1 values(1);
617617
connection default;
618618
let $wait_condition=
619619
select count(*) = 1 from information_schema.processlist
620-
where state = "Locked" and info = "insert into t1 values(1)";
620+
where state = "Table lock" and info = "insert into t1 values(1)";
621621
--source include/wait_condition.inc
622622
let $tlwb= `show status like 'Table_locks_waited'`;
623623
unlock tables;

mysql-test/t/lock_sync.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ set debug_sync= 'now WAIT_FOR parked';
7171
connection default;
7272
--echo # Wait until this LOCK TABLES statement starts waiting for table lock.
7373
let $wait_condition= select count(*)= 1 from information_schema.processlist
74-
where state= 'Locked' and
74+
where state= 'Table lock' and
7575
info='lock table t1 write';
7676
--source include/wait_condition.inc
7777
--echo # Allow SELECT ... FOR UPDATE to resume.

mysql-test/t/multi_update.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ connection updater;
496496
# Wait till "alter table t1 ..." of session changer is in work.
497497
# = There is one session is in state "Locked".
498498
let $wait_condition= select count(*)= 1 from information_schema.processlist
499-
where state= 'Locked';
499+
where state= 'Table lock';
500500
--source include/wait_condition.inc
501501
send update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a;
502502

@@ -507,7 +507,7 @@ connection locker;
507507
# are in work.
508508
# = There are two session is in state "Locked".
509509
let $wait_condition= select count(*)= 2 from information_schema.processlist
510-
where state= 'Locked';
510+
where state= 'Table lock';
511511
--source include/wait_condition.inc
512512
unlock tables;
513513

mysql-test/t/query_cache_28249.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,18 @@ connection user3;
5858
# Typical information_schema.processlist content after sufficient sleep time
5959
# ID USER COMMAND TIME STATE INFO
6060
# ....
61-
# 2 root Query 5 Locked SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
61+
# 2 root Query 5 Table lock SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
6262
# ....
6363
# XXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6464
# The values marked with 'X' must be reached.
6565
--echo # Poll till the select of connection user1 is blocked by the write lock on t1.
6666
let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist
67-
WHERE state = 'Locked'
67+
WHERE state = 'Table lock'
6868
AND info = '$select_for_qc';
6969
--source include/wait_condition.inc
7070
eval
7171
SELECT user,command,state,info FROM information_schema.processlist
72-
WHERE state = 'Locked'
72+
WHERE state = 'Table lock'
7373
AND info = '$select_for_qc';
7474
INSERT INTO t1 VALUES (4);
7575

mysql-test/t/sp_notembedded.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ set session low_priority_updates=on;
322322
connection rl_wait;
323323
let $wait_condition=
324324
select count(*) = 1 from information_schema.processlist
325-
where state = "Locked" and
325+
where state = "Table lock" and
326326
info = "update t1 set value='updated' where value='old'";
327327
--source include/wait_condition.inc
328328

mysql-test/t/status.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ let $ID= `select connection_id()`;
5858
connection con2;
5959
--echo # Switched to connection: con2
6060
# wait for the other query to start executing
61-
let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Locked";
61+
let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST where ID = $ID and STATE = "Table lock";
6262
--source include/wait_condition.inc
6363
unlock tables;
6464

mysys/thr_lock.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
396396
struct timespec wait_timeout;
397397
enum enum_thr_lock_result result= THR_LOCK_ABORTED;
398398
my_bool can_deadlock= test(data->owner->info->n_cursors);
399+
const char *old_proc_info;
399400
DBUG_ENTER("wait_for_lock");
400401

401402
/*
@@ -434,6 +435,9 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
434435
thread_var->current_cond= cond;
435436
data->cond= cond;
436437

438+
old_proc_info= proc_info_hook(NULL, "Table lock",
439+
__func__, __FILE__, __LINE__);
440+
437441
if (can_deadlock)
438442
set_timespec(wait_timeout, table_lock_wait_timeout);
439443
while (!thread_var->abort || in_wait_list)
@@ -504,6 +508,9 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
504508
thread_var->current_mutex= 0;
505509
thread_var->current_cond= 0;
506510
pthread_mutex_unlock(&thread_var->mutex);
511+
512+
proc_info_hook(NULL, old_proc_info, __func__, __FILE__, __LINE__);
513+
507514
DBUG_RETURN(result);
508515
}
509516

sql/lock.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
310310
break;
311311
}
312312
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
313-
thd_proc_info(thd, "Locked");
314313
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
315314
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
316315
sql_lock->lock_count * sizeof(*sql_lock->locks));

0 commit comments

Comments
 (0)