summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2003-11-20 18:12:49 +0200
committerunknown <bell@sanja.is.com.ua>2003-11-20 18:12:49 +0200
commit03e04c02cdf33c443db5b46b48f8c4ef02ad1b9e (patch)
tree00ae1853b3692c50d3d0037e71afd411cf9ab8ed
parent24bdf9560396936bcdb540d785bcaf981b68d457 (diff)
downloadmariadb-git-03e04c02cdf33c443db5b46b48f8c4ef02ad1b9e.tar.gz
database invalidation invalidate queries only of given database (BUG#1898)
mysql-test/r/query_cache.result: test of drop database mysql-test/t/query_cache.test: test of drop database sql/sql_cache.cc: database invalidation invalidate queries only of given database every freed block header marked as FREE even if it will be merged to make moving & deleting tables block safe layout fixed (too long line)
-rw-r--r--mysql-test/r/query_cache.result11
-rw-r--r--mysql-test/t/query_cache.test4
-rw-r--r--sql/sql_cache.cc34
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);