mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
8d0dc9b58b
FLUSH TABLES <list> WITH READ LOCK are incompatible" to be pushed as separate patch. Replaced thread state name "Waiting for table", which was used by threads waiting for a metadata lock or table flush, with a set of names which better reflect types of resources being waited for. Also replaced "Table lock" thread state name, which was used by threads waiting on thr_lock.c table level lock, with more elaborate "Waiting for table level lock", to make it more consistent with other thread state names. Updated test cases and their results according to these changes. Fixed sys_vars.query_cache_wlock_invalidate_func test to not to wait for timeout of wait_condition.inc script. mysql-test/r/query_cache.result: Added test coverage for query_cache_wlock_invalidate behavior for implicitly locked tables. mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result: Fixed sys_vars.query_cache_wlock_invalidate_func test to not to wait for timeout of wait_condition.inc script. Reverted changes to test which introduced timeout and replaced waiting condition with a more appropriate one. Test coverage for query_cache_wlock_invalidate behavior for implicitly locked tables was added to query_cache.test. mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test: Fixed sys_vars.query_cache_wlock_invalidate_func test to not to wait for timeout of wait_condition.inc script. Reverted changes to test which introduced timeout and replaced waiting condition with a more appropriate one. Test coverage for query_cache_wlock_invalidate behavior for implicitly locked tables was added to query_cache.test. mysql-test/t/query_cache.test: Added test coverage for query_cache_wlock_invalidate behavior for implicitly locked tables. mysys/thr_lock.c: Replaced "Table lock" thread state name, which was used by threads waiting on thr_lock.c table level lock, with more elaborate "Waiting for table level lock", to make it consistent with thread state names which are used while waiting for metadata locks and table flush. sql/mdl.cc: Replaced thread state name "Waiting for table", which was used by threads waiting for a metadata lock or table flush, with a set of names which better reflect types of resources being waited for. To implement this: - Adjusted MDL_wait::timed_wait() to take thread state name as parameter. - Introduced method of MDL_key class which allows to get thread state name to be used while waiting for resource corresponding to the key and changed code to use it. Added array translating namespaces to thread state names as part of this change. sql/mdl.h: To implement this: - Adjusted MDL_wait::timed_wait() to take thread state name as parameter. - Introduced method of MDL_key class which allows to get thread state name to be used while waiting for resource corresponding to the key and changed code to use it. Added array translating namespaces to thread state names as part of this change. sql/sql_base.cc: Replaced thread state name "Waiting for table", which was used by threads waiting for table flush, with a more elaborate "Waiting for table flush".
124 lines
4.2 KiB
Text
124 lines
4.2 KiB
Text
### 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
|
|
--source include/not_embedded.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 Waiting for table level lock 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 = 'Waiting for table level lock'
|
|
AND info = '$select_for_qc';
|
|
--source include/wait_condition.inc
|
|
eval
|
|
SELECT user,command,state,info FROM information_schema.processlist
|
|
WHERE state = 'Waiting for table level 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;
|
|
|