mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
389fba8403
This patch corrects a misstake in the test case for bug patch 43658. There was a race in the test case when the thread id was retrieved from the processlist. The result was that the same thread id was signalled twice and one thread id wasn't signalled at all. The affected platforms appears to be limited to linux. mysql-test/r/query_cache_debug.result: There was a race in the test case when the thread id was retrieved from the processlist. The result was that the same thread id was signalled twice and one thread id wasn't signalled at all. mysql-test/t/query_cache_debug.test: There was a race in the test case when the thread id was retrieved from the processlist. The result was that the same thread id was signalled twice and one thread id wasn't signalled at all.
181 lines
7.5 KiB
Text
181 lines
7.5 KiB
Text
flush status;
|
|
set query_cache_type=DEMAND;
|
|
set global query_cache_size= 1024*768;
|
|
drop table if exists t1;
|
|
create table t1 (a varchar(100));
|
|
insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
|
|
Activate debug hook and attempt to retrieve the statement from the cache.
|
|
set session debug='+d,wait_in_query_cache_insert';
|
|
select SQL_CACHE * from t1;;
|
|
On a second connection; clear the query cache.
|
|
show status like 'Qcache_queries_in_cache';
|
|
Variable_name Value
|
|
Qcache_queries_in_cache 1
|
|
set global query_cache_size= 0;
|
|
Signal the debug hook to release the lock.
|
|
select id from information_schema.processlist where state='wait_in_query_cache_insert' into @thread_id;
|
|
kill query @thread_id;
|
|
Show query cache status.
|
|
show status like 'Qcache_queries_in_cache';
|
|
Variable_name Value
|
|
Qcache_queries_in_cache 0
|
|
set global query_cache_size= 0;
|
|
use test;
|
|
drop table t1;
|
|
SET @old_concurrent_insert= @@GLOBAL.concurrent_insert;
|
|
SET @old_query_cache_size= @@GLOBAL.query_cache_size;
|
|
DROP TABLE IF EXISTS t1, t2;
|
|
CREATE TABLE t1 (a INT);
|
|
CREATE TABLE t2 (a INT);
|
|
INSERT INTO t1 VALUES (1),(2),(3);
|
|
SET GLOBAL concurrent_insert= 1;
|
|
SET GLOBAL query_cache_size= 1024*512;
|
|
SET GLOBAL query_cache_type= ON;
|
|
# Switch to connection con1
|
|
SET SESSION debug='+d,wait_after_query_cache_invalidate';
|
|
# Send concurrent insert, will wait in the query cache table invalidate
|
|
INSERT INTO t1 VALUES (4);
|
|
# Switch to connection default
|
|
# Wait for concurrent insert to reach the debug point
|
|
# Switch to connection con2
|
|
# Send SELECT that shouldn't be cached
|
|
SELECT * FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
# Switch to connection default
|
|
# Notify the concurrent insert to proceed
|
|
SELECT ID FROM INFORMATION_SCHEMA.PROCESSLIST
|
|
WHERE STATE = 'wait_after_query_cache_invalidate' INTO @thread_id;
|
|
KILL QUERY @thread_id;
|
|
# Switch to connection con1
|
|
# Gather insert result
|
|
SHOW STATUS LIKE "Qcache_queries_in_cache";
|
|
Variable_name Value
|
|
Qcache_queries_in_cache 0
|
|
# Test that it's cacheable
|
|
SELECT * FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
SHOW STATUS LIKE "Qcache_queries_in_cache";
|
|
Variable_name Value
|
|
Qcache_queries_in_cache 1
|
|
# Disconnect
|
|
# Restore defaults
|
|
RESET QUERY CACHE;
|
|
DROP TABLE t1,t2;
|
|
SET GLOBAL concurrent_insert= DEFAULT;
|
|
SET GLOBAL query_cache_size= DEFAULT;
|
|
SET GLOBAL query_cache_type= DEFAULT;
|
|
#
|
|
# Bug43758 Query cache can lock up threads in 'freeing items' state
|
|
#
|
|
FLUSH STATUS;
|
|
SET GLOBAL query_cache_type=DEMAND;
|
|
SET GLOBAL query_cache_size= 1024*768;
|
|
DROP TABLE IF EXISTS t1,t2,t3,t4,t5;
|
|
CREATE TABLE t1 (a VARCHAR(100));
|
|
CREATE TABLE t2 (a VARCHAR(100));
|
|
CREATE TABLE t3 (a VARCHAR(100));
|
|
CREATE TABLE t4 (a VARCHAR(100));
|
|
CREATE TABLE t5 (a VARCHAR(100));
|
|
INSERT INTO t1 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
|
|
INSERT INTO t2 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
|
|
INSERT INTO t3 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
|
|
INSERT INTO t4 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
|
|
INSERT INTO t5 VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
|
|
=================================== Connection thd1
|
|
**
|
|
** Load Query Cache with a result set and one table.
|
|
**
|
|
SELECT SQL_CACHE * FROM t1;
|
|
a
|
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|
*************************************************************************
|
|
** We want to accomplish the following state:
|
|
** - Query cache status: TABLE_FLUSH_IN_PROGRESS
|
|
** - THD1: invalidate_table_internal (iterating query blocks)
|
|
** - THD2: query_cache_insert (cond_wait)
|
|
** - THD3: query_cache_insert (cond_wait)
|
|
** - No thread should be holding the structure_guard_mutex.
|
|
**
|
|
** First step is to place a DELETE-statement on the debug hook just
|
|
** before the mutex lock in invalidate_table_internal.
|
|
** This will allow new result sets to be written into the QC.
|
|
**
|
|
SET SESSION debug='+d,wait_in_query_cache_invalidate1';
|
|
SET SESSION debug='+d,wait_in_query_cache_invalidate2';
|
|
DELETE FROM t1 WHERE a like '%a%';;
|
|
=================================== Connection default
|
|
** Assert that the expect process status is obtained.
|
|
**
|
|
=================================== Connection thd2
|
|
** On THD2: Insert a result into the cache. This attempt will be blocked
|
|
** because of a debug hook placed just before the mutex lock after which
|
|
** the first part of the result set is written.
|
|
SET SESSION debug='+d,wait_in_query_cache_insert';
|
|
SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3;
|
|
=================================== Connection thd3
|
|
** On THD3: Insert another result into the cache and block on the same
|
|
** debug hook.
|
|
SET SESSION debug='+d,wait_in_query_cache_insert';
|
|
SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;;
|
|
=================================== Connection default
|
|
** Assert that the two SELECT-stmt threads to reach the hook.
|
|
**
|
|
**
|
|
** Signal the DELETE thread, THD1, to continue. It will enter the mutex
|
|
** lock and set query cache status to TABLE_FLUSH_IN_PROGRESS and then
|
|
** unlock the mutex before stopping on the next debug hook.
|
|
SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate1' LIMIT 1 INTO @flush_thread_id;
|
|
KILL QUERY @flush_thread_id;
|
|
** Assert that we reach the next debug hook.
|
|
**
|
|
** Signal the remaining debug hooks blocking THD2 and THD3.
|
|
** The threads will grab the guard mutex enter the wait condition and
|
|
** and finally release the mutex. The threads will continue to wait
|
|
** until a broadcast signal reaches them causing both threads to
|
|
** come alive and check the condition.
|
|
SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id ASC LIMIT 1 INTO @thread_id;
|
|
KILL QUERY @thread_id;
|
|
SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_insert' ORDER BY id DESC LIMIT 1 INTO @thread_id;
|
|
KILL QUERY @thread_id;
|
|
**
|
|
** Finally signal the DELETE statement on THD1 one last time.
|
|
** The stmt will complete the query cache invalidation and return
|
|
** cache status to NO_FLUSH_IN_PROGRESS. On the status change
|
|
** One signal will be sent to the thread group waiting for executing
|
|
** invalidations and a broadcast signal will be sent to the thread
|
|
** group holding result set writers.
|
|
SELECT SQL_NO_CACHE id FROM information_schema.processlist WHERE state='wait_in_query_cache_invalidate2' LIMIT 1 INTO @flush_thread_id;
|
|
KILL QUERY @flush_thread_id;
|
|
**
|
|
*************************************************************************
|
|
** No tables should be locked
|
|
=================================== Connection thd2
|
|
a
|
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|
DELETE FROM t1;
|
|
DELETE FROM t2;
|
|
DELETE FROM t3;
|
|
=================================== Connection thd3
|
|
a
|
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
|
DELETE FROM t4;
|
|
DELETE FROM t5;
|
|
=================================== Connection thd1
|
|
** Done.
|
|
SET GLOBAL query_cache_size= 0;
|
|
# Restore defaults
|
|
RESET QUERY CACHE;
|
|
FLUSH STATUS;
|
|
DROP TABLE t1,t2,t3,t4,t5;
|
|
SET GLOBAL query_cache_size= DEFAULT;
|
|
SET GLOBAL query_cache_type= DEFAULT;
|