From bccbd5c493a5350a7dd36e0349f2ad6d05863e89 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Aug 2007 16:11:53 -0300 Subject: [PATCH 1/2] Bug#28587 SELECT is blocked by INSERT waiting on read lock, even with low_priority_updates The problem is that a SELECT on one thread is blocked by INSERT ... ON DUPLICATE KEY UPDATE on another thread even when low_priority_updates is activated. The solution is to possibly downgrade the lock type to the setting of low_priority_updates if the INSERT cannot be concurrent. sql/sql_insert.cc: Possibly downgrade lock type to the the setting of low_priority_updates if if the INSERT cannot be concurrent. --- sql/sql_insert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index bd21d929291..f07af393070 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -417,7 +417,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, if (duplic == DUP_UPDATE || duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT) { - *lock_type= TL_WRITE; + *lock_type= TL_WRITE_DEFAULT; return; } From 97844e982b8e75752bf145392982a9c8562cd125 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Aug 2007 16:19:23 -0300 Subject: [PATCH 2/2] Post-merge test case with wait_condition for Bug#28587 mysql-test/r/insert_update.result: Post-merge: add test case result for Bug#28587. mysql-test/t/insert_update.test: Post-merge: add test case for Bug#28587. --- mysql-test/r/insert_update.result | 19 +++++++++++++++++ mysql-test/t/insert_update.test | 35 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index 704cf444681..3aec9594d36 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -407,3 +407,22 @@ select if( @stamp1 = @stamp2, "correct", "wrong"); if( @stamp1 = @stamp2, "correct", "wrong") correct drop table t1; +connection: default +set low_priority_updates=1; +drop table if exists t1; +create table t1 (a int, b int, unique key t1$a (a)); +lock table t1 read; +connection: update +set low_priority_updates=1; +show variables like 'low_priority_updates'; +Variable_name Value +low_priority_updates ON +insert into t1 values (1, 2) ON DUPLICATE KEY UPDATE b = 2;; +connection: select +select * from t1; +a b +connection: default +select * from t1; +a b +drop table t1; +set low_priority_updates=default; diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test index 67f21731afe..aad241e031f 100644 --- a/mysql-test/t/insert_update.test +++ b/mysql-test/t/insert_update.test @@ -306,3 +306,38 @@ insert into t1(f1) values(1) on duplicate key update f1=1; select @stamp2:=f2 from t1; select if( @stamp1 = @stamp2, "correct", "wrong"); drop table t1; + +# +# Bug#28587 SELECT is blocked by INSERT waiting on read lock, even with low_priority_updates +# +--echo connection: default +set low_priority_updates=1; +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a int, b int, unique key t1$a (a)); +lock table t1 read; +connect (update,localhost,root,,); +connection update; +--echo connection: update +set low_priority_updates=1; +show variables like 'low_priority_updates'; +let $ID= `select connection_id()`; +--send insert into t1 values (1, 2) ON DUPLICATE KEY UPDATE b = 2; +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; +--source include/wait_condition.inc +connect (select,localhost,root,,); +--echo connection: select +select * from t1; +connection default; +--echo connection: default +select * from t1; +connection default; +disconnect update; +disconnect select; +drop table t1; +set low_priority_updates=default;