diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:00:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:00:34 +0000 |
commit | 3f619478f796eddbba6e39502fe941b285dd97b1 (patch) | |
tree | e2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/main/query_cache_debug.test | |
parent | Initial commit. (diff) | |
download | mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.tar.xz mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.zip |
Adding upstream version 1:10.11.6.upstream/1%10.11.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysql-test/main/query_cache_debug.test')
-rw-r--r-- | mysql-test/main/query_cache_debug.test | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/mysql-test/main/query_cache_debug.test b/mysql-test/main/query_cache_debug.test new file mode 100644 index 00000000..5942e6f4 --- /dev/null +++ b/mysql-test/main/query_cache_debug.test @@ -0,0 +1,362 @@ +--source include/not_embedded.inc +--source include/have_query_cache.inc +--source include/have_debug_sync.inc +--source include/long_test.inc +--source include/no_valgrind_without_big.inc + +set global query_cache_type= ON; +set @save_query_cache_size=@@global.query_cache_size; +SET @save_concurrent_insert= @@GLOBAL.concurrent_insert; + +# +# Bug #30887 Server crashes on SET GLOBAL query_cache_size=0 +# +flush status; +set query_cache_type=DEMAND; +set global query_cache_size= 1024*768; +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (a varchar(100)); +insert into t1 values ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); +connect (bug30887con1, localhost, root, ,test); +connect (bug30887con2, localhost, root, ,test); + +connection bug30887con1; +--echo Activate debug hook and attempt to retrieve the statement from the cache. +set debug_sync="wait_in_query_cache_insert SIGNAL parked WAIT_FOR go"; +--send select SQL_CACHE * from t1; + +connection default; +set debug_sync="now WAIT_FOR parked"; + +connection bug30887con2; +--echo clear the query cache. +show status like 'Qcache_queries_in_cache'; +set global query_cache_size= 0; + +connection default; +--echo Signal the debug hook to release the lock. +set debug_sync="now SIGNAL go"; + +--echo Show query cache status. +show status like 'Qcache_queries_in_cache'; + +connection bug30887con1; +--reap + +disconnect bug30887con1; +disconnect bug30887con2; +connection default; +set debug_sync= 'RESET'; +set global query_cache_size= 0; +use test; +drop table t1; + +# +# Bug#41098: Query Cache returns wrong result with concurrent insert +# +--disable_view_protocol + +--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); + +SET GLOBAL concurrent_insert= 1; +SET GLOBAL query_cache_size= 1024*512; +SET GLOBAL query_cache_type= ON; + +connect(con1,localhost,root,,test,,); +connect(con2,localhost,root,,test,,); + +connection con1; +SET DEBUG_SYNC = "wait_after_query_cache_invalidate SIGNAL parked WAIT_FOR go"; +--echo # Send concurrent insert, will wait in the query cache table invalidate +--send INSERT INTO t1 VALUES (4) + +connection default; +--echo # Wait for concurrent insert to reach the debug point +SET DEBUG_SYNC = "now WAIT_FOR parked"; + +connection con2; +--echo # Send SELECT that shouldn't be cached +SELECT * FROM t1; + +connection default; +--echo # Notify the concurrent insert to proceed +SET DEBUG_SYNC = "now SIGNAL go"; + +connection con1; +--echo # Gather insert result +--reap +SHOW STATUS LIKE "Qcache_queries_in_cache"; +--echo # Test that it's cacheable +SELECT * FROM t1; +SHOW STATUS LIKE "Qcache_queries_in_cache"; + +disconnect con1; +disconnect con2; + +connection default; +--echo # Restore defaults +SET DEBUG_SYNC= 'RESET'; +RESET QUERY CACHE; +DROP TABLE t1,t2; +SET GLOBAL concurrent_insert= DEFAULT; +SET GLOBAL query_cache_size= DEFAULT; +SET GLOBAL query_cache_type= DEFAULT; +--enable_view_protocol + +--echo # +--echo # Bug43758 Query cache can lock up threads in 'freeing items' state +--echo # +FLUSH STATUS; +SET GLOBAL query_cache_type=DEMAND; +SET GLOBAL query_cache_size= 1024*768; +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3,t4,t5; +--enable_warnings +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'); + +connect (thd2, localhost, root, ,test); +connect (thd3, localhost, root, ,test); +connect (thd1, localhost, root, ,test); + +connection thd1; +--echo ** +--echo ** Load Query Cache with a result set and one table. +--echo ** +SELECT SQL_CACHE * FROM t1; +--echo ************************************************************************* +--echo ** We want to accomplish the following state: +--echo ** - Query cache status: TABLE_FLUSH_IN_PROGRESS +--echo ** - THD1: invalidate_table_internal (iterating query blocks) +--echo ** - THD2: query_cache_insert (cond_wait) +--echo ** - THD3: query_cache_insert (cond_wait) +--echo ** - No thread should be holding the structure_guard_mutex. +--echo ** +--echo ** First step is to place a DELETE-statement on the debug hook just +--echo ** before the mutex lock in invalidate_table_internal. +--echo ** This will allow new result sets to be written into the QC. +--echo ** +SET DEBUG_SYNC="wait_in_query_cache_invalidate1 SIGNAL parked1_1 WAIT_FOR go1_1"; +SET DEBUG_SYNC="wait_in_query_cache_invalidate2 SIGNAL parked1_2 WAIT_FOR go1_2"; +--send DELETE FROM t1 WHERE a like '%a%'; + +connection default; +--echo ** Assert that the expect process status is obtained. +SET DEBUG_SYNC="now WAIT_FOR parked1_1"; +-- echo ** + +connection thd2; +--echo ** On THD2: Insert a result into the cache. This attempt will be blocked +--echo ** because of a debug hook placed just before the mutex lock after which +--echo ** the first part of the result set is written. +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1"; +--send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3 + +connection default; +--echo ** Assert that the SELECT-stmt thread reaches the sync point. +SET DEBUG_SYNC="now WAIT_FOR parked2"; +--echo ** +--echo ** + +connection thd3; +--echo ** On THD3: Insert another result into the cache and block on the same +--echo ** debug hook. +SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1"; +--send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5 + +connection default; +--echo ** Assert that the SELECT-stmt thread reaches the sync point. +SET DEBUG_SYNC="now WAIT_FOR parked3"; +--echo ** +--echo ** + +--echo ** Signal the DELETE thread, THD1, to continue. It will enter the mutex +--echo ** lock and set query cache status to TABLE_FLUSH_IN_PROGRESS and then +--echo ** unlock the mutex before stopping on the next debug hook. +SET DEBUG_SYNC="now SIGNAL go1_1"; +--echo ** Assert that we reach the next debug hook. +SET DEBUG_SYNC="now WAIT_FOR parked1_2"; + +--echo ** +--echo ** Signal the remaining debug hooks blocking THD2 and THD3. +--echo ** The threads will grab the guard mutex enter the wait condition and +--echo ** and finally release the mutex. The threads will continue to wait +--echo ** until a broadcast signal reaches them causing both threads to +--echo ** come alive and check the condition. + +# Before sending signals back-to-back, we have to ensure the previous signal +# was received +let $wait_condition= select count(*)=3 from information_schema.processlist where state like "%debug%"; +source include/wait_condition.inc; +SET DEBUG_SYNC="now SIGNAL go2"; +let $wait_condition= select count(*)=2 from information_schema.processlist where state like "%debug%"; +source include/wait_condition.inc; +SET DEBUG_SYNC="now SIGNAL go3"; +let $wait_condition= select count(*)=1 from information_schema.processlist where state like "%debug%"; +source include/wait_condition.inc; + +--echo ** +--echo ** Finally signal the DELETE statement on THD1 one last time. +--echo ** The stmt will complete the query cache invalidation and return +--echo ** cache status to NO_FLUSH_IN_PROGRESS. On the status change +--echo ** One signal will be sent to the thread group waiting for executing +--echo ** invalidations and a broadcast signal will be sent to the thread +--echo ** group holding result set writers. +SET DEBUG_SYNC="now SIGNAL go1_2"; +let $wait_condition= select count(*)=0 from information_schema.processlist where state like "%debug%"; +source include/wait_condition.inc; + +--echo ** +--echo ************************************************************************* +--echo ** No tables should be locked +connection thd2; +reap; +DELETE FROM t1; +DELETE FROM t2; +DELETE FROM t3; + +connection thd3; +reap; +DELETE FROM t4; +DELETE FROM t5; + +connection thd1; +reap; + +--echo ** Done. + +connection default; +disconnect thd1; +disconnect thd2; +disconnect thd3; +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL query_cache_size= 0; + +connection default; +--echo # 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; + +--echo # +--echo # Bug#56822: Add a thread state for sessions waiting on the query cache lock +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1 (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; + +connect(con1,localhost,root,,test,,); +connect(con2,localhost,root,,test,,); + +connection con1; +SET DEBUG_SYNC = "wait_in_query_cache_invalidate2 SIGNAL parked WAIT_FOR go"; +--echo # Send INSERT, will wait in the query cache table invalidation +--send INSERT INTO t1 VALUES (4); + +connection default; +--echo # Wait for insert to reach the debug point +SET DEBUG_SYNC = "now WAIT_FOR parked"; + +connection con2; +--echo # Send a query that should wait on the query cache lock +--send RESET QUERY CACHE + +connection default; +--echo # Wait for the state to be reflected in the processlist +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = "Waiting for query cache lock" AND info = "RESET QUERY CACHE"; +--source include/wait_condition.inc +--echo # Signal that the query cache can be unlocked +SET DEBUG_SYNC="now SIGNAL go"; + +connection con1; +--reap +disconnect con1; + +connection con2; +--reap +disconnect con2; + +connection default; +--echo # Restore defaults +SET DEBUG_SYNC= 'RESET'; +RESET QUERY CACHE; +DROP TABLE t1; +SET GLOBAL query_cache_size= @save_query_cache_size; +SET GLOBAL query_cache_type= DEFAULT; + +--echo # +--echo # MDEV-14526: MariaDB keeps crashing under load when +--echo # query_cache_type is changed +--echo # + +CREATE TABLE t1 ( + `id` int(10) NOT NULL AUTO_INCREMENT, + `k` int(10) default '0', + PRIMARY KEY (`id`)) +ENGINE=MyISAM; + +INSERT IGNORE INTO t1 VALUES + (NULL,1),(NULL,8),(NULL,NULL),(NULL,NULL),(NULL,4),(NULL,9),(NULL,7), + (NULL,3),(NULL,NULL),(NULL,2),(NULL,3),(NULL,NULL),(NULL,2),(NULL,7), + (NULL,1),(NULL,2),(NULL,4),(NULL,NULL),(NULL,1),(NULL,1),(NULL,4); + +SET GLOBAL query_cache_size= 1024*1024; +SET GLOBAL query_cache_type= 1; + +--connect (con2,localhost,root,,test) +--connect (con1,localhost,root,,test) +set debug_sync="wait_in_query_cache_store_query SIGNAL parked WAIT_FOR go"; +--send SELECT DISTINCT id FROM t1 WHERE id BETWEEN 5603 AND 16218 ORDER BY k + +--connection default + +set debug_sync="now WAIT_FOR parked"; +--connection con2 +--send SET GLOBAL query_cache_type= 0; + +--connection default +set debug_sync="now SIGNAL go"; + +--connection con1 +--reap +--connection con2 +--reap + +# Cleanup +--disconnect con1 +--disconnect con2 +--connection default +set debug_sync= 'RESET'; +DROP TABLE t1; +SET GLOBAL query_cache_size=@save_query_cache_size; +SET GLOBAL query_cache_type= DEFAULT; +SET @@GLOBAL.concurrent_insert=@save_concurrent_insert; + +--echo # End of 5.5 tests |