List:Commits« Previous MessageNext Message »
From:Matthias Leich Date:November 28 2008 3:45pm
Subject:bzr commit into mysql-5.1 branch (Matthias.Leich:2713) Bug#40179 Bug#41098
View as plain text  
#At file:///work2/5.1/mysql-5.1-bugteam-work1/

 2713 Matthias Leich	2008-11-28
      - Fix for Bug#40179 Test main.query_cache failing randomly on Pushbuild, test weakness
      - disable the test suffering from Bug#41098 Query Cache returns wrong result with
                                                  concurrent insert
      - additional improvements
      
      Details:
      - Move the test for the historic bug
        Bug 28249 Query Cache returns wrong result with concurrent insert / certain lock
        into its own testscript query_cache_28249.test.
      - query_cache.test:
        - replace error numbers with error names
        - remove trailing spaces, replace tabs with spaces
        - reset of @@global.log_bin_trust_function_creators to its original value
          at the end of the test
      - query_cache_28249.test:
        - replace sleep 5 with poll routine
        - avoid random differences caused by concurrent_inserts effects
        - improved comments and formatting
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-07-24 13:41:55 +0000
+++ b/mysql-test/r/query_cache.result	2008-11-28 15:45:34 +0000
@@ -1116,12 +1116,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//
@@ -1615,41 +1616,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
 #

=== 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-11-28 15:45:34 +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 = 'Locked'
+  AND info = 'SELECT *, (SELECT COUNT(*) FROM t2) FROM t1';
+user	command	state	info
+root	Query	Locked	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-11-17 20:25:27 +0000
+++ b/mysql-test/t/disabled.def	2008-11-28 15:45:34 +0000
@@ -12,3 +12,4 @@
 federated_transactions   : Bug#29523 Transactions do not work
 log_tables.test                       : Bug #37798: main.log_tables fails randomly on powermacg5 and windows
 slow_query_log_func.test              : Bug #37962: *_func tests containing sleeps/race conditions
+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-03-26 16:36:12 +0000
+++ b/mysql-test/t/query_cache.test	2008-11-28 15:45:34 +0000
@@ -300,7 +300,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;
@@ -410,10 +410,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;
 
 #
@@ -435,7 +435,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";
@@ -537,7 +537,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.
 #
@@ -554,21 +554,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,'�,'�' 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;
@@ -602,12 +602,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
@@ -801,9 +801,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//
 
@@ -1016,7 +1017,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;
@@ -1025,7 +1026,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
@@ -1046,7 +1047,7 @@ create table t1 (a char);
 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
@@ -1182,75 +1183,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 #
@@ -1260,7 +1192,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
@@ -1278,7 +1210,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;

=== 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-11-28 15:45:34 +0000
@@ -0,0 +1,124 @@
+### 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 sufficient sleep time
+#   ID  USER  COMMAND  TIME  STATE   INFO
+#   ....
+#   2   root  Query       5  Locked  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'
+  AND info = '$select_for_qc';
+--source include/wait_condition.inc
+eval
+SELECT user,command,state,info FROM information_schema.processlist
+WHERE state = 'Locked'
+  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-5.1 branch (Matthias.Leich:2713) Bug#40179 Bug#41098Matthias Leich28 Nov