#At file:///work2/6.0/mysql-6.0-bugteam-combined/
2823 Matthias Leich 2008-12-19 [merge]
Merge 5.1 -> 6.0 of fix for Bug 40179 Test main.query_cache failing randomly on Pushbuild,
test weakness
added:
mysql-test/r/query_cache_28249.result
mysql-test/t/query_cache_28249.test
modified:
mysql-test/r/query_cache.result
mysql-test/t/disabled.def
mysql-test/t/query_cache.test
=== modified file 'mysql-test/r/query_cache.result'
--- a/mysql-test/r/query_cache.result 2008-10-20 09:16:47 +0000
+++ b/mysql-test/r/query_cache.result 2008-12-19 08:12:18 +0000
@@ -1066,12 +1066,13 @@ create procedure `p1`()
begin
select a, f1() from t1;
end//
+SET @log_bin_trust_function_creators = @@global.log_bin_trust_function_creators;
SET GLOBAL log_bin_trust_function_creators = 1;
call p1()//
a f1()
1 2
2 2
-SET GLOBAL log_bin_trust_function_creators = 0;
+SET GLOBAL log_bin_trust_function_creators = @log_bin_trust_function_creators;
drop procedure p1//
drop function f1//
drop table t1//
@@ -1559,41 +1560,6 @@ id
DROP PROCEDURE proc29856;
DROP TABLE t1;
SET GLOBAL query_cache_size= default;
-Bug#28249 Query Cache returns wrong result with concurrent insert/ certain lock
-set GLOBAL query_cache_type=1;
-set GLOBAL query_cache_limit=10000;
-set GLOBAL query_cache_min_res_unit=0;
-set GLOBAL query_cache_size= 100000;
-flush tables;
-drop table if exists t1, t2;
-create table t1 (a int);
-create table t2 (a int);
-insert into t1 values (1),(2),(3);
-Locking table T2 with a write lock.
-lock table t2 write;
-Select blocked by write lock.
-select *, (select count(*) from t2) from t1;;
-Sleeing is ok, because selecting should be done very fast.
-Inserting into table T1.
-insert into t1 values (4);
-Unlocking the tables.
-unlock tables;
-Collecting result from previously blocked select.
-Next select should contain 4 rows, as the insert is long finished.
-select *, (select count(*) from t2) from t1;
-a (select count(*) from t2)
-1 0
-2 0
-3 0
-4 0
-reset query cache;
-select *, (select count(*) from t2) from t1;
-a (select count(*) from t2)
-1 0
-2 0
-3 0
-4 0
-drop table t1,t2;
#
# Bug#25132 disabled query cache: Qcache_free_blocks = 1
#
@@ -1679,7 +1645,7 @@ SELECT * FROM t1 UNION SELECT SQL_NO_CAC
ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
SELECT * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1);
ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
-SELECT * FROM t1 WHERE a IN
+SELECT * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
SELECT SQL_CACHE SQL_NO_CACHE * FROM t1;
@@ -1694,10 +1660,10 @@ SELECT SQL_NO_CACHE * FROM t1 UNION SELE
ERROR 42000: Incorrect usage/placement of 'SQL_CACHE'
SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
ERROR 42000: Incorrect usage/placement of 'SQL_NO_CACHE'
-SELECT SQL_CACHE * FROM t1 WHERE a IN
+SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT SQL_NO_CACHE a FROM t1);
ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
-SELECT SQL_CACHE * FROM t1 WHERE a IN
+SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
ERROR 42S22: Unknown column 'SQL_NO_CACHE' in 'field list'
DROP TABLE t1;
=== added file 'mysql-test/r/query_cache_28249.result'
--- a/mysql-test/r/query_cache_28249.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/query_cache_28249.result 2008-12-19 08:12:18 +0000
@@ -0,0 +1,62 @@
+SET @query_cache_type= @@global.query_cache_type;
+SET @query_cache_limit= @@global.query_cache_limit;
+SET @query_cache_min_res_unit= @@global.query_cache_min_res_unit;
+SET @query_cache_size= @@global.query_cache_size;
+# Bug#28249 Query Cache returns wrong result with concurrent insert/ certain lock
+# Establish connections user1,user2,user3 (user=root)
+# Switch to connection user1
+SET GLOBAL query_cache_type=1;
+SET GLOBAL query_cache_limit=10000;
+SET GLOBAL query_cache_min_res_unit=0;
+SET GLOBAL query_cache_size= 100000;
+FLUSH TABLES;
+DROP TABLE IF EXISTS t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+# Switch to connection user2
+LOCK TABLE t2 WRITE;
+# Switch to connection user1
+# "send" the next select, "reap" the result later.
+# The select will be blocked by the write lock on the t1.
+SELECT *, (SELECT COUNT(*) FROM t2) FROM t1;
+# Switch to connection user3
+# Poll till the select of connection user1 is blocked by the write lock on t1.
+SELECT user,command,state,info FROM information_schema.processlist
+WHERE state = 'Table Lock'
+ AND info = 'SELECT *, (SELECT COUNT(*) FROM t2) FROM t1';
+user command state info
+root Query Table lock SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+INSERT INTO t1 VALUES (4);
+# Switch to connection user2
+UNLOCK TABLES;
+# Switch to connection user1
+# Collecting ("reap") the result from the previously blocked select.
+# The printing of the result (varies between 3 and 4 rows) set has to be suppressed.
+# Switch to connection user3
+# The next select enforces that effects of "concurrent_inserts" like the
+# record with a = 4 is missing in result sets can no more happen.
+SELECT 1 FROM t1 WHERE a = 4;
+1
+1
+# Switch to connection user1
+# The next result set must contain 4 rows.
+SELECT *, (SELECT COUNT(*) FROM t2) FROM t1;
+a (SELECT COUNT(*) FROM t2)
+1 0
+2 0
+3 0
+4 0
+RESET QUERY CACHE;
+SELECT *, (SELECT COUNT(*) FROM t2) FROM t1;
+a (SELECT COUNT(*) FROM t2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2;
+# Switch to connection default + close connections user1,user2,user3
+SET GLOBAL query_cache_type= @query_cache_type;
+SET GLOBAL query_cache_limit= @query_cache_limit;
+SET GLOBAL query_cache_min_res_unit= @query_cache_min_res_unit;
+SET GLOBAL query_cache_size= @query_cache_size;
=== modified file 'mysql-test/t/disabled.def'
--- a/mysql-test/t/disabled.def 2008-12-10 09:02:11 +0000
+++ b/mysql-test/t/disabled.def 2008-12-19 08:12:18 +0000
@@ -19,6 +19,7 @@ csv_alter_table : Bug#33696 2008-01
cast : Bug#35594 2008-03-27 main.cast fails on Windows2003-64
backup_triggers_and_events : Bug#37762 2008-07-01 rafal Test fails on remove_file for unknown reasons
backup_no_be : Bug#38023 2008-07-16 rafal Test triggers valgrind warnings described in the bug
-log_output_basic : Bug #40988 log_output_basic.test succeeded though syntactically false.
+log_output_basic : Bug #40988 log_output_basic.test succeeded though syntactically false.
wait_timeout_func : Bug #41225 joro wait_timeout_func fails
-kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enoiugh for pushbuild.
+kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
+query_cache_28249 : Bug#41098 Query Cache returns wrong result with concurrent insert
=== modified file 'mysql-test/t/query_cache.test'
--- a/mysql-test/t/query_cache.test 2008-10-09 10:58:51 +0000
+++ b/mysql-test/t/query_cache.test 2008-12-19 08:12:18 +0000
@@ -287,7 +287,7 @@ select * from t1;
select * from t1;
show status like "Qcache_queries_in_cache";
insert delayed into t1 values (4);
---sleep 5 # Wait for insert delayed to be executed.
+--sleep 5 # Wait for insert delayed to be executed.
select a from t1;
show status like "Qcache_queries_in_cache";
drop table t1;
@@ -397,10 +397,10 @@ create table t1(id int auto_increment pr
insert into t1 values (NULL), (NULL), (NULL);
select * from t1 where id=2;
alter table t1 rename to t2;
--- error 1146
+--error ER_NO_SUCH_TABLE
select * from t1 where id=2;
drop table t2;
--- error 1146
+--error ER_NO_SUCH_TABLE
select * from t1 where id=2;
#
@@ -422,7 +422,7 @@ create table t1 (a int);
insert into t1 values (1),(2),(3);
show status like "Qcache_queries_in_cache";
select * from t1 into outfile "query_cache.out.file";
---error 1086
+--error ER_FILE_EXISTS_ERROR
select * from t1 into outfile "query_cache.out.file";
select * from t1 limit 1 into dumpfile "query_cache.dump.file";
show status like "Qcache_queries_in_cache";
@@ -527,7 +527,7 @@ drop table t1;
# If at least one of the above variables has changed,
# the cached query can't be reused. In the below test
# absolutely the same query is used several times,
-# SELECT should fetch different results for every instance.
+# SELECT should fetch different results for every instance.
# No hits should be produced.
# New cache entry should appear for every SELECT.
#
@@ -544,21 +544,21 @@ show status like "Qcache_queries_in_cach
# Change collation_connection and run the same query again
#
set collation_connection=koi8r_bin;
-SELECT a,'�,'�'� FROM t1;
+SELECT a,'�,'�'� FROM t1;
show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
#
# Now change character_set_client and run the same query again
#
set character_set_client=cp1251;
-SELECT a,'�,'�'� FROM t1;
+SELECT a,'�,'�'� FROM t1;
show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
#
# And finally change character_set_results and run the same query again
#
set character_set_results=cp1251;
-SELECT a,'�,'�'� FROM t1;
+SELECT a,'�,'�'� FROM t1;
show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
SET NAMES default;
@@ -592,12 +592,12 @@ insert into t1 set c = repeat('x',24);
insert into t1 set c = concat(repeat('x',24),'x');
insert into t1 set c = concat(repeat('x',24),'w');
insert into t1 set c = concat(repeat('x',24),'y');
-set max_sort_length=200;
+set max_sort_length=200;
select c from t1 order by c, id;
reset query cache;
set max_sort_length=20;
select c from t1 order by c, id;
-set max_sort_length=200;
+set max_sort_length=200;
select c from t1 order by c, id;
set max_sort_length=default;
# sql_mode
@@ -791,9 +791,10 @@ create procedure `p1`()
begin
select a, f1() from t1;
end//
+SET @log_bin_trust_function_creators = @@global.log_bin_trust_function_creators;
SET GLOBAL log_bin_trust_function_creators = 1;
call p1()//
-SET GLOBAL log_bin_trust_function_creators = 0;
+SET GLOBAL log_bin_trust_function_creators = @log_bin_trust_function_creators;
drop procedure p1//
drop function f1//
@@ -1006,7 +1007,7 @@ set GLOBAL query_cache_size= default;
#
-# Bug #28897 UUID() returns non-unique values when query cache is enabled
+# Bug#28897 UUID() returns non-unique values when query cache is enabled
#
set GLOBAL query_cache_size=1000000;
@@ -1015,7 +1016,7 @@ create table t1 (a char);
insert into t1 values ('c');
let $q1= `select UUID(), a from t1`;
-let $q2= `select UUID(), a from t1`;
+let $q2= `select UUID(), a from t1`;
# disabling the logging of the query because the UUIDs are different each run.
--disable_query_log
@@ -1030,7 +1031,7 @@ set GLOBAL query_cache_size= default;
# Bug #29053 SQL_CACHE in UNION causes non-deterministic functions to be cached
#
-# This syntax is no longer allowed, therefore the test case has been commented
+# This syntax is no longer allowed, therefore the test case has been commented
# out.
# See test for Bug#35020 below.
#set GLOBAL query_cache_size=1000000;
@@ -1039,7 +1040,7 @@ set GLOBAL query_cache_size= default;
#insert into t1 values ('c');
#
#let $q1= `select RAND() from t1 union select sql_cache 1 from t1;`;
-#let $q2= `select RAND() from t1 union select sql_cache 1 from t1;`;
+#let $q2= `select RAND() from t1 union select sql_cache 1 from t1;`;
#
# disabling the logging of the query because the times are different each run.
#--disable_query_log
@@ -1175,75 +1176,6 @@ DROP TABLE t1;
SET GLOBAL query_cache_size= default;
#
-# Bug #28249 Query Cache returns wrong result with concurrent insert / certain lock
-#
---echo Bug#28249 Query Cache returns wrong result with concurrent insert/ certain lock
-connect (user1,localhost,root,,test,,);
-connect (user2,localhost,root,,test,,);
-connect (user3,localhost,root,,test,,);
-
-connection user1;
-
-set GLOBAL query_cache_type=1;
-set GLOBAL query_cache_limit=10000;
-set GLOBAL query_cache_min_res_unit=0;
-set GLOBAL query_cache_size= 100000;
-
-flush tables;
---disable_warnings
-drop table if exists t1, t2;
---enable_warnings
-create table t1 (a int);
-create table t2 (a int);
-insert into t1 values (1),(2),(3);
-connection user2;
---echo Locking table T2 with a write lock.
-lock table t2 write;
-
-connection user1;
---echo Select blocked by write lock.
---send select *, (select count(*) from t2) from t1;
---echo Sleeing is ok, because selecting should be done very fast.
-sleep 5;
-
-connection user3;
---echo Inserting into table T1.
-insert into t1 values (4);
-
-connection user2;
---echo Unlocking the tables.
-unlock tables;
-
-connection user1;
---echo Collecting result from previously blocked select.
-#
-# Since the lock ordering rule in thr_multi_lock depends on
-# pointer values, from execution to execution we might have
-# different lock order, and therefore, sometimes lock t1 and block
-# on t2, and sometimes block on t2 right away. In the second case,
-# the following insert succeeds, and only then this select can
-# proceed, and we actually test nothing, as the very first select
-# returns 4 rows right away.
-# It's fine to have a test case that covers the problematic area
-# at least once in a while.
-# We, however, need to disable the result log here to make the
-# test repeatable.
---disable_result_log
---reap
---enable_result_log
---echo Next select should contain 4 rows, as the insert is long finished.
-select *, (select count(*) from t2) from t1;
-reset query cache;
-select *, (select count(*) from t2) from t1;
-
-drop table t1,t2;
-
-connection default;
-disconnect user1;
-disconnect user2;
-disconnect user3;
-
-#
--echo #
--echo # Bug#25132 disabled query cache: Qcache_free_blocks = 1
--echo #
@@ -1253,7 +1185,7 @@ set global query_cache_type=0;
show status like 'Qcache_free_blocks';
--echo Restore default values.
-# Bug #28211 RENAME DATABASE and query cache don't play nicely together
+# Bug#28211 RENAME DATABASE and query cache don't play nicely together
#
# TODO: enable these tests when RENAME DATABASE is implemented.
# --disable_warnings
@@ -1271,7 +1203,7 @@ show status like 'Qcache_free_blocks';
# show status like 'Qcache_queries_in_cache';
# drop database db2;
# set global query_cache_size=default;
-#
+#
# --disable_warnings
# drop database if exists db1;
# drop database if exists db3;
@@ -1353,9 +1285,9 @@ SET @v = ( SELECT SQL_NO_CACHE 1 );
# Keywords 'SQL_CACHE' and 'SQL_NO_CACHE' are allowed as column names.
# Hence the error messages are not intuitive.
#
---error ER_BAD_FIELD_ERROR
+--error ER_BAD_FIELD_ERROR
SELECT a FROM t1 WHERE a IN ( SELECT SQL_CACHE a FROM t1 );
---error ER_BAD_FIELD_ERROR
+--error ER_BAD_FIELD_ERROR
SELECT a FROM t1 WHERE a IN ( SELECT SQL_NO_CACHE a FROM t1 );
--error ER_BAD_FIELD_ERROR
SELECT ( SELECT SQL_CACHE a FROM t1 );
@@ -1380,7 +1312,7 @@ SELECT * FROM t1 UNION SELECT SQL_NO_CAC
--error ER_BAD_FIELD_ERROR
SELECT * FROM t1 WHERE a IN (SELECT SQL_NO_CACHE a FROM t1);
--error ER_BAD_FIELD_ERROR
-SELECT * FROM t1 WHERE a IN
+SELECT * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
--error ER_WRONG_USAGE
SELECT SQL_CACHE SQL_NO_CACHE * FROM t1;
@@ -1395,10 +1327,10 @@ SELECT SQL_NO_CACHE * FROM t1 UNION SELE
--error ER_CANT_USE_OPTION_HERE
SELECT SQL_NO_CACHE * FROM t1 UNION SELECT SQL_NO_CACHE * FROM t1;
--error ER_BAD_FIELD_ERROR
-SELECT SQL_CACHE * FROM t1 WHERE a IN
+SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT SQL_NO_CACHE a FROM t1);
--error ER_BAD_FIELD_ERROR
-SELECT SQL_CACHE * FROM t1 WHERE a IN
+SELECT SQL_CACHE * FROM t1 WHERE a IN
(SELECT a FROM t1 UNION SELECT SQL_NO_CACHE a FROM t1);
DROP TABLE t1;
=== added file 'mysql-test/t/query_cache_28249.test'
--- a/mysql-test/t/query_cache_28249.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/query_cache_28249.test 2008-12-19 08:12:18 +0000
@@ -0,0 +1,123 @@
+### t/query_cache_28249.test ###
+#
+# Test for
+# Bug#28249 Query Cache returns wrong result with concurrent insert / certain lock
+#
+# Last modification:
+# 2008-11-27 mleich - Move this test out of query_cache.test
+# - Fix Bug#40179 Test main.query_cache failing randomly on Pushbuild,
+# test weakness
+# - Minor improvements (comments,formatting etc.)
+#
+
+--source include/have_query_cache.inc
+
+SET @query_cache_type= @@global.query_cache_type;
+SET @query_cache_limit= @@global.query_cache_limit;
+SET @query_cache_min_res_unit= @@global.query_cache_min_res_unit;
+SET @query_cache_size= @@global.query_cache_size;
+
+--echo # Bug#28249 Query Cache returns wrong result with concurrent insert/ certain lock
+--echo # Establish connections user1,user2,user3 (user=root)
+connect (user1,localhost,root,,test,,);
+connect (user2,localhost,root,,test,,);
+connect (user3,localhost,root,,test,,);
+
+--echo # Switch to connection user1
+connection user1;
+
+SET GLOBAL query_cache_type=1;
+SET GLOBAL query_cache_limit=10000;
+SET GLOBAL query_cache_min_res_unit=0;
+SET GLOBAL query_cache_size= 100000;
+
+FLUSH TABLES;
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+--enable_warnings
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2),(3);
+
+--echo # Switch to connection user2
+connection user2;
+LOCK TABLE t2 WRITE;
+
+--echo # Switch to connection user1
+connection user1;
+--echo # "send" the next select, "reap" the result later.
+--echo # The select will be blocked by the write lock on the t1.
+let $select_for_qc =
+SELECT *, (SELECT COUNT(*) FROM t2) FROM t1;
+send;
+eval $select_for_qc;
+
+--echo # Switch to connection user3
+connection user3;
+# Typical information_schema.processlist content after sufficient sleep time
+# ID USER COMMAND TIME STATE INFO
+# ....
+# 2 root Query 5 Table Lock SELECT *, (SELECT COUNT(*) FROM t2) FROM t1
+# ....
+# XXXXXXXXXX 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 = 'Table Lock'
+ AND info = '$select_for_qc';
+--source include/wait_condition.inc
+eval
+SELECT user,command,state,info FROM information_schema.processlist
+WHERE state = 'Table Lock'
+ AND info = '$select_for_qc';
+INSERT INTO t1 VALUES (4);
+
+--echo # Switch to connection user2
+connection user2;
+UNLOCK TABLES;
+
+--echo # Switch to connection user1
+connection user1;
+#
+# Since the lock ordering rule in thr_multi_lock depends on
+# pointer values, from execution to execution we might have
+# different lock order, and therefore, sometimes lock t1 and block
+# on t2, and sometimes block on t2 right away. In the second case,
+# the following insert succeeds, and only then this select can
+# proceed, and we actually test nothing, as the very first select
+# returns 4 rows right away.
+# It's fine to have a test case that covers the problematic area
+# at least once in a while.
+--echo # Collecting ("reap") the result from the previously blocked select.
+--echo # The printing of the result (varies between 3 and 4 rows) set has to be suppressed.
+--disable_result_log
+--reap
+--enable_result_log
+
+--echo # Switch to connection user3
+connection user3;
+--echo # The next select enforces that effects of "concurrent_inserts" like the
+--echo # record with a = 4 is missing in result sets can no more happen.
+SELECT 1 FROM t1 WHERE a = 4;
+
+--echo # Switch to connection user1
+connection user1;
+--echo # The next result set must contain 4 rows.
+# If not, we have a regression of Bug#28249
+eval $select_for_qc;
+RESET QUERY CACHE;
+eval $select_for_qc;
+
+DROP TABLE t1,t2;
+
+--echo # Switch to connection default + close connections user1,user2,user3
+connection default;
+disconnect user1;
+disconnect user2;
+disconnect user3;
+
+SET GLOBAL query_cache_type= @query_cache_type;
+SET GLOBAL query_cache_limit= @query_cache_limit;
+SET GLOBAL query_cache_min_res_unit= @query_cache_min_res_unit;
+SET GLOBAL query_cache_size= @query_cache_size;
+
| Thread |
|---|
| • bzr commit into mysql-6.0-bugteam branch (Matthias.Leich:2823) | Matthias Leich | 19 Dec |