Commit 1a330ada authored by Horst Hunger's avatar Horst Hunger

Fix for bug 39484 after review. I inserted the review results (also including the patches itself):

"Release_lock("hello")" is now also successful when delivering NULL, replaced two sleeps by wait_condition. The last two "sleep 1" have not been replaced as all tried wait conditions leaded to nondeterministic results, especially to succeeding concurrent updates. To replace the sleeps there should be some time planned (or internal knowledge of the server may help).
 
parent 23b1da15
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
# $engine_type storage engine to be tested # $engine_type storage engine to be tested
# #
# Last update: # Last update:
# 2009-02-13 HH "Release_lock("hello")" is now also successful when delivering NULL,
# replaced two sleeps by wait_condition. The last two "sleep 1" have not been
# replaced as all tried wait conditions leaded to nondeterministic results, especially
# to succeeding concurrent updates. To replace the sleeps there should be some time
# planned (or internal knowledge of the server may help).
# 2006-08-02 ML test refactored # 2006-08-02 ML test refactored
# old name was t/innodb_concurrent.test # old name was t/innodb_concurrent.test
# main code went into include/concurrent.inc # main code went into include/concurrent.inc
...@@ -21,7 +26,6 @@ ...@@ -21,7 +26,6 @@
# #
connection default; connection default;
# #
# Show prerequisites for this test. # Show prerequisites for this test.
# #
...@@ -50,8 +54,6 @@ GRANT USAGE ON test.* TO mysqltest@localhost; ...@@ -50,8 +54,6 @@ GRANT USAGE ON test.* TO mysqltest@localhost;
# #
# Preparatory cleanup. # Preparatory cleanup.
# #
DO release_lock("hello");
DO release_lock("hello2");
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
...@@ -86,13 +88,14 @@ drop table if exists t1; ...@@ -86,13 +88,14 @@ drop table if exists t1;
connection thread2; connection thread2;
--echo ** Start transaction for thread 2 --echo ** Start transaction for thread 2
begin; begin;
--echo ** Update will cause a table scan and a new ULL will --echo ** Update will cause a table scan and a new ULL will
--echo ** be created and blocked on the first row where tipo=11. --echo ** be created and blocked on the first row where tipo=11.
send update t1 set eta=1+get_lock("hello",10)*0 where tipo=11; send update t1 set eta=1+get_lock("hello",10)*0 where tipo=11;
sleep 1;
--echo ** connection thread1 --echo ** connection thread1
connection thread1; connection thread1;
let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
--source include/wait_condition.inc
--echo ** Start new transaction for thread 1 --echo ** Start new transaction for thread 1
begin; begin;
--echo ** Update on t1 will cause a table scan which will be blocked because --echo ** Update on t1 will cause a table scan which will be blocked because
...@@ -111,7 +114,9 @@ drop table if exists t1; ...@@ -111,7 +114,9 @@ drop table if exists t1;
} }
--echo ** Release user level name lock from thread 1. This will cause the ULL --echo ** Release user level name lock from thread 1. This will cause the ULL
--echo ** on thread 2 to end its wait. --echo ** on thread 2 to end its wait.
select release_lock("hello"); # Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
DO release_lock("hello");
--echo ** Table is now updated with a new eta on tipo=22 for thread 1. --echo ** Table is now updated with a new eta on tipo=22 for thread 1.
select * from t1; select * from t1;
...@@ -119,7 +124,9 @@ drop table if exists t1; ...@@ -119,7 +124,9 @@ drop table if exists t1;
connection thread2; connection thread2;
--echo ** Release the lock and collect result from update on thread 2 --echo ** Release the lock and collect result from update on thread 2
reap; reap;
select release_lock("hello"); # Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
DO release_lock("hello");
--echo ** Table should have eta updates where tipo=11 but updates made by --echo ** Table should have eta updates where tipo=11 but updates made by
--echo ** thread 1 shouldn't be visible yet. --echo ** thread 1 shouldn't be visible yet.
select * from t1; select * from t1;
...@@ -183,10 +190,11 @@ drop table t1; ...@@ -183,10 +190,11 @@ drop table t1;
--echo ** This will cause a hang on the first row where tipo=1 until the --echo ** This will cause a hang on the first row where tipo=1 until the
--echo ** blocking ULL is released. --echo ** blocking ULL is released.
send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1; send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1;
sleep 1;
--echo ** connection thread1 --echo ** connection thread1
connection thread1; connection thread1;
let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
--source include/wait_condition.inc
--echo ** Start transaction on thread 1 --echo ** Start transaction on thread 1
begin; begin;
--echo ** Update on t1 will cause a table scan which will be blocked because --echo ** Update on t1 will cause a table scan which will be blocked because
...@@ -204,7 +212,9 @@ drop table t1; ...@@ -204,7 +212,9 @@ drop table t1;
update t1 set tipo=1 where tipo=2; update t1 set tipo=1 where tipo=2;
} }
--echo ** Release ULL. This will release the next waiting ULL on thread 2. --echo ** Release ULL. This will release the next waiting ULL on thread 2.
select release_lock("hello"); # Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically)the success of the following
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
DO release_lock("hello");
--echo ** The table should still be updated with updates for thread 1 only: --echo ** The table should still be updated with updates for thread 1 only:
select * from t1; select * from t1;
...@@ -212,7 +222,9 @@ drop table t1; ...@@ -212,7 +222,9 @@ drop table t1;
connection thread2; connection thread2;
--echo ** Release the lock and collect result from thread 2: --echo ** Release the lock and collect result from thread 2:
reap; reap;
select release_lock("hello"); # Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
DO release_lock("hello");
--echo ** Seen from thread 2 the table should have been updated on four --echo ** Seen from thread 2 the table should have been updated on four
--echo ** places. --echo ** places.
select * from t1; select * from t1;
...@@ -264,15 +276,18 @@ drop table t1; ...@@ -264,15 +276,18 @@ drop table t1;
--echo ** Update will create a table scan which creates a ULL where a=2; --echo ** Update will create a table scan which creates a ULL where a=2;
--echo ** this will hang waiting on thread 1. --echo ** this will hang waiting on thread 1.
send update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2; send update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2;
sleep 1;
--echo ** connection thread1 --echo ** connection thread1
connection thread1; connection thread1;
let $wait_condition= select count(*)= 1 from information_schema.processlist where state= 'User lock';
--source include/wait_condition.inc
--echo ** Insert new values to t1 from thread 1; this created an implicit --echo ** Insert new values to t1 from thread 1; this created an implicit
--echo ** commit since there are no on-going transactions. --echo ** commit since there are no on-going transactions.
insert into t1 values (1,1); insert into t1 values (1,1);
--echo ** Release the ULL (thread 2 updates will finish). --echo ** Release the ULL (thread 2 updates will finish).
select release_lock("hello2"); # Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
DO release_lock("hello2");
--echo ** ..but thread 1 will still see t1 as if nothing has happend: --echo ** ..but thread 1 will still see t1 as if nothing has happend:
select * from t1; select * from t1;
...@@ -280,7 +295,9 @@ drop table t1; ...@@ -280,7 +295,9 @@ drop table t1;
connection thread2; connection thread2;
--echo ** Collect results from thread 2 and release the lock. --echo ** Collect results from thread 2 and release the lock.
reap; reap;
select release_lock("hello2"); # Due to Bug#32782 User lock hash fails to find lock, which probably also cause Bug#39484 (main.concurrent_innodb_safelog fails sporadically) the success of the following
# is also guaranteed for NULL. Replaced SELECT by DO (no result).
DO release_lock("hello2");
--echo ** The table should look like the original+updates for thread 2, --echo ** The table should look like the original+updates for thread 2,
--echo ** and consist of new rows: --echo ** and consist of new rows:
select * from t1; select * from t1;
...@@ -534,6 +551,9 @@ drop table t1; ...@@ -534,6 +551,9 @@ drop table t1;
connection thread2; connection thread2;
begin; begin;
send delete from t1 where tipo=2; send delete from t1 where tipo=2;
# The sleep has not been replaced as all tried wait conditions leaded to sporadically
# succeding update in the following thread. Also the used status variables '%lock%' and
# 'innodb_deleted_rows' and infos in processlist where not sucessful.
sleep 1; sleep 1;
--echo ** connection thread1 --echo ** connection thread1
...@@ -594,8 +614,11 @@ drop table t1; ...@@ -594,8 +614,11 @@ drop table t1;
connection thread2; connection thread2;
begin; begin;
send delete from t1 where tipo=2; send delete from t1 where tipo=2;
# The sleep has not been replaced as all tried wait conditions leaded to sporadically
# succeding update in the following thread. Also the used status variables '%lock%' and
# 'innodb_deleted_rows' and infos in processlist where not sucessful.
sleep 1; sleep 1;
--echo ** connection thread1 --echo ** connection thread1
connection thread1; connection thread1;
begin; begin;
......
...@@ -7,8 +7,6 @@ SELECT @@global.innodb_locks_unsafe_for_binlog; ...@@ -7,8 +7,6 @@ SELECT @@global.innodb_locks_unsafe_for_binlog;
0 0
# keep_locks == 1 # keep_locks == 1
GRANT USAGE ON test.* TO mysqltest@localhost; GRANT USAGE ON test.* TO mysqltest@localhost;
DO release_lock("hello");
DO release_lock("hello2");
drop table if exists t1; drop table if exists t1;
** **
...@@ -36,7 +34,7 @@ get_lock("hello",10) ...@@ -36,7 +34,7 @@ get_lock("hello",10)
** connection thread2 ** connection thread2
** Start transaction for thread 2 ** Start transaction for thread 2
begin; begin;
** Update will cause a table scan and a new ULL will ** Update will cause a table scan and a new ULL will
** be created and blocked on the first row where tipo=11. ** be created and blocked on the first row where tipo=11.
update t1 set eta=1+get_lock("hello",10)*0 where tipo=11; update t1 set eta=1+get_lock("hello",10)*0 where tipo=11;
** connection thread1 ** connection thread1
...@@ -51,9 +49,7 @@ update t1 set eta=2 where tipo=22; ...@@ -51,9 +49,7 @@ update t1 set eta=2 where tipo=22;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction ERROR HY000: Lock wait timeout exceeded; try restarting transaction
** Release user level name lock from thread 1. This will cause the ULL ** Release user level name lock from thread 1. This will cause the ULL
** on thread 2 to end its wait. ** on thread 2 to end its wait.
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** Table is now updated with a new eta on tipo=22 for thread 1. ** Table is now updated with a new eta on tipo=22 for thread 1.
select * from t1; select * from t1;
eta tipo c eta tipo c
...@@ -70,9 +66,7 @@ eta tipo c ...@@ -70,9 +66,7 @@ eta tipo c
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk 90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
** connection thread2 ** connection thread2
** Release the lock and collect result from update on thread 2 ** Release the lock and collect result from update on thread 2
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** Table should have eta updates where tipo=11 but updates made by ** Table should have eta updates where tipo=11 but updates made by
** thread 1 shouldn't be visible yet. ** thread 1 shouldn't be visible yet.
select * from t1; select * from t1;
...@@ -194,9 +188,7 @@ begin; ...@@ -194,9 +188,7 @@ begin;
update t1 set tipo=1 where tipo=2; update t1 set tipo=1 where tipo=2;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction ERROR HY000: Lock wait timeout exceeded; try restarting transaction
** Release ULL. This will release the next waiting ULL on thread 2. ** Release ULL. This will release the next waiting ULL on thread 2.
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** The table should still be updated with updates for thread 1 only: ** The table should still be updated with updates for thread 1 only:
select * from t1; select * from t1;
eta tipo c eta tipo c
...@@ -213,9 +205,7 @@ eta tipo c ...@@ -213,9 +205,7 @@ eta tipo c
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk 90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
** connection thread2 ** connection thread2
** Release the lock and collect result from thread 2: ** Release the lock and collect result from thread 2:
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** Seen from thread 2 the table should have been updated on four ** Seen from thread 2 the table should have been updated on four
** places. ** places.
select * from t1; select * from t1;
...@@ -319,9 +309,7 @@ update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2; ...@@ -319,9 +309,7 @@ update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2;
** commit since there are no on-going transactions. ** commit since there are no on-going transactions.
insert into t1 values (1,1); insert into t1 values (1,1);
** Release the ULL (thread 2 updates will finish). ** Release the ULL (thread 2 updates will finish).
select release_lock("hello2"); DO release_lock("hello2");
release_lock("hello2")
1
** ..but thread 1 will still see t1 as if nothing has happend: ** ..but thread 1 will still see t1 as if nothing has happend:
select * from t1; select * from t1;
a b a b
...@@ -332,9 +320,7 @@ a b ...@@ -332,9 +320,7 @@ a b
1 1 1 1
** connection thread2 ** connection thread2
** Collect results from thread 2 and release the lock. ** Collect results from thread 2 and release the lock.
select release_lock("hello2"); DO release_lock("hello2");
release_lock("hello2")
1
** The table should look like the original+updates for thread 2, ** The table should look like the original+updates for thread 2,
** and consist of new rows: ** and consist of new rows:
select * from t1; select * from t1;
......
...@@ -7,8 +7,6 @@ SELECT @@global.innodb_locks_unsafe_for_binlog; ...@@ -7,8 +7,6 @@ SELECT @@global.innodb_locks_unsafe_for_binlog;
1 1
# keep_locks == 0 # keep_locks == 0
GRANT USAGE ON test.* TO mysqltest@localhost; GRANT USAGE ON test.* TO mysqltest@localhost;
DO release_lock("hello");
DO release_lock("hello2");
drop table if exists t1; drop table if exists t1;
** **
...@@ -36,7 +34,7 @@ get_lock("hello",10) ...@@ -36,7 +34,7 @@ get_lock("hello",10)
** connection thread2 ** connection thread2
** Start transaction for thread 2 ** Start transaction for thread 2
begin; begin;
** Update will cause a table scan and a new ULL will ** Update will cause a table scan and a new ULL will
** be created and blocked on the first row where tipo=11. ** be created and blocked on the first row where tipo=11.
update t1 set eta=1+get_lock("hello",10)*0 where tipo=11; update t1 set eta=1+get_lock("hello",10)*0 where tipo=11;
** connection thread1 ** connection thread1
...@@ -50,9 +48,7 @@ begin; ...@@ -50,9 +48,7 @@ begin;
update t1 set eta=2 where tipo=22; update t1 set eta=2 where tipo=22;
** Release user level name lock from thread 1. This will cause the ULL ** Release user level name lock from thread 1. This will cause the ULL
** on thread 2 to end its wait. ** on thread 2 to end its wait.
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** Table is now updated with a new eta on tipo=22 for thread 1. ** Table is now updated with a new eta on tipo=22 for thread 1.
select * from t1; select * from t1;
eta tipo c eta tipo c
...@@ -69,9 +65,7 @@ eta tipo c ...@@ -69,9 +65,7 @@ eta tipo c
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk 90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
** connection thread2 ** connection thread2
** Release the lock and collect result from update on thread 2 ** Release the lock and collect result from update on thread 2
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** Table should have eta updates where tipo=11 but updates made by ** Table should have eta updates where tipo=11 but updates made by
** thread 1 shouldn't be visible yet. ** thread 1 shouldn't be visible yet.
select * from t1; select * from t1;
...@@ -192,9 +186,7 @@ begin; ...@@ -192,9 +186,7 @@ begin;
** do not match the WHERE condition are released. ** do not match the WHERE condition are released.
update t1 set tipo=1 where tipo=2; update t1 set tipo=1 where tipo=2;
** Release ULL. This will release the next waiting ULL on thread 2. ** Release ULL. This will release the next waiting ULL on thread 2.
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** The table should still be updated with updates for thread 1 only: ** The table should still be updated with updates for thread 1 only:
select * from t1; select * from t1;
eta tipo c eta tipo c
...@@ -211,9 +203,7 @@ eta tipo c ...@@ -211,9 +203,7 @@ eta tipo c
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk 90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
** connection thread2 ** connection thread2
** Release the lock and collect result from thread 2: ** Release the lock and collect result from thread 2:
select release_lock("hello"); DO release_lock("hello");
release_lock("hello")
1
** Seen from thread 2 the table should have been updated on four ** Seen from thread 2 the table should have been updated on four
** places. ** places.
select * from t1; select * from t1;
...@@ -317,9 +307,7 @@ update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2; ...@@ -317,9 +307,7 @@ update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2;
** commit since there are no on-going transactions. ** commit since there are no on-going transactions.
insert into t1 values (1,1); insert into t1 values (1,1);
** Release the ULL (thread 2 updates will finish). ** Release the ULL (thread 2 updates will finish).
select release_lock("hello2"); DO release_lock("hello2");
release_lock("hello2")
1
** ..but thread 1 will still see t1 as if nothing has happend: ** ..but thread 1 will still see t1 as if nothing has happend:
select * from t1; select * from t1;
a b a b
...@@ -330,9 +318,7 @@ a b ...@@ -330,9 +318,7 @@ a b
1 1 1 1
** connection thread2 ** connection thread2
** Collect results from thread 2 and release the lock. ** Collect results from thread 2 and release the lock.
select release_lock("hello2"); DO release_lock("hello2");
release_lock("hello2")
1
** The table should look like the original+updates for thread 2, ** The table should look like the original+updates for thread 2,
** and consist of new rows: ** and consist of new rows:
select * from t1; select * from t1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment