From a1ceb1bd049a14a72f1ccf1cc8556e6930c07af5 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Thu, 20 Nov 2003 18:12:49 +0200 Subject: [PATCH] database invalidation invalidate queries only of given database (BUG#1898) --- mysql-test/r/query_cache.result | 11 +++++++++-- mysql-test/t/query_cache.test | 4 ++++ sql/sql_cache.cc | 34 +++++++++++++++++++++++++++------ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 83d2e439fbc..c7554211a1a 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -365,16 +365,23 @@ insert into mysqltest.t1 (a) values (1); select * from mysqltest.t1 where i is null; i a 1 1 +create table t1(a int); +select * from t1; +a +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 select * from mysqltest.t1; i a 1 1 show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 1 +Qcache_queries_in_cache 2 drop database mysqltest; show status like "Qcache_queries_in_cache"; Variable_name Value -Qcache_queries_in_cache 0 +Qcache_queries_in_cache 1 +drop table t1; create table t1 (a char(1) not null); insert into t1 values("รก"); select * from t1; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 2ab5504f84b..ad0dc80e2f7 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -251,10 +251,14 @@ select * from mysqltest.t1 where i is null; # # drop db # +create table t1(a int); +select * from t1; +show status like "Qcache_queries_in_cache"; select * from mysqltest.t1; show status like "Qcache_queries_in_cache"; drop database mysqltest; show status like "Qcache_queries_in_cache"; +drop table t1; # # Charset convertion (cp1251_koi8 always present) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 5d525c7be4e..8610fcb8f22 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1151,9 +1151,29 @@ void Query_cache::invalidate(char *db) if (query_cache_size > 0) { DUMP(this); - /* invalidate_table reduce list while only root of list remain */ - while (tables_blocks !=0 ) - invalidate_table(tables_blocks); + restart_search: + if (tables_blocks) + { + Query_cache_block *curr= tables_blocks; + Query_cache_block *next; + do + { + next= curr->next; + if (strcmp(db, (char*)(curr->table()->db())) == 0) + invalidate_table(curr); + /* + invalidate_table can freed block on which point 'next' (if + table of this block used only in queries which was deleted + by invalidate_table). As far as we do not allocate new blocks + and mark all headers of freed blocks as 'FREE' (even if they are + merged with other blocks) we can just test type of block + to be sure that block is not deleted + */ + if (next->type == Query_cache_block::FREE) + goto restart_search; + curr= next; + } while (curr != tables_blocks); + } } STRUCT_UNLOCK(&structure_guard_mutex); } @@ -2158,9 +2178,11 @@ void Query_cache::free_memory_block(Query_cache_block *block) { DBUG_ENTER("Query_cache::free_memory_block"); block->used=0; - DBUG_PRINT("qcache",("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx", - (ulong) first_block, (ulong) block,block->pnext, - (ulong) block->pprev)); + block->type= Query_cache_block::FREE; // mark block as free in any case + DBUG_PRINT("qcache", + ("first_block 0x%lx, block 0x%lx, pnext 0x%lx pprev 0x%lx", + (ulong) first_block, (ulong) block,block->pnext, + (ulong) block->pprev)); if (block->pnext != first_block && block->pnext->is_free()) block = join_free_blocks(block, block->pnext); -- 2.30.9