summaryrefslogtreecommitdiff
path: root/sql/sql_cache.h
diff options
context:
space:
mode:
authorkroki/tomash@moonlight.intranet <>2006-08-22 11:47:52 +0400
committerkroki/tomash@moonlight.intranet <>2006-08-22 11:47:52 +0400
commit0f0ddc398a5b68f3a67794c82e7a40cb44a6e402 (patch)
tree6da805e8e859d377d16c5f512dfe034ba5c7ecb2 /sql/sql_cache.h
parentbf10578fde502a81f56eaf91d556930ae0327893 (diff)
downloadmariadb-git-0f0ddc398a5b68f3a67794c82e7a40cb44a6e402.tar.gz
BUG#21051: RESET QUERY CACHE very slow when query_cache_type=0
There were two problems: RESET QUERY CACHE took a long time to complete and other threads were blocked during this time. The patch does three things: 1 fixes a bug with improper use of test-lock-test_again technique. AKA Double-Checked Locking is applicable here only in few places. 2 Somewhat improves performance of RESET QUERY CACHE. Do my_hash_reset() instead of deleting elements one by one. Note however that the slowdown also happens when inserting into sorted list of free blocks, should be rewritten using balanced tree. 3 Makes RESET QUERY CACHE non-blocking. The patch adjusts the locking protocol of the query cache in the following way: it introduces a flag flush_in_progress, which is set when Query_cache::flush_cache() is in progress. This call sets the flag on enter, and then releases the lock. Every other call is able to acquire the lock, but does nothing if flush_in_progress is set (as if the query cache is disabled). The only exception is the concurrent calls to Query_cache::flush_cache(), that are blocked until the flush is over. When leaving Query_cache::flush_cache(), the lock is acquired and the flag is reset, and one thread waiting on Query_cache::flush_cache() (if any) is notified that it may proceed.
Diffstat (limited to 'sql/sql_cache.h')
-rw-r--r--sql/sql_cache.h17
1 files changed, 16 insertions, 1 deletions
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 29d314d3c44..a66067159e2 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -195,7 +195,6 @@ extern "C"
byte *query_cache_table_get_key(const byte *record, uint *length,
my_bool not_used);
}
-void query_cache_insert(NET *thd, const char *packet, ulong length);
extern "C" void query_cache_invalidate_by_MyISAM_filename(const char* filename);
@@ -241,6 +240,12 @@ public:
ulong free_memory, queries_in_cache, hits, inserts, refused,
free_memory_blocks, total_blocks, lowmem_prunes;
+private:
+ pthread_cond_t COND_flush_finished;
+ bool flush_in_progress;
+
+ void free_query_internal(Query_cache_block *point);
+
protected:
/*
The following mutex is locked when searching or changing global
@@ -249,6 +254,12 @@ protected:
LOCK SEQUENCE (to prevent deadlocks):
1. structure_guard_mutex
2. query block (for operation inside query (query block/results))
+
+ Thread doing cache flush releases the mutex once it sets
+ flush_in_progress flag, so other threads may bypass the cache as
+ if it is disabled, not waiting for reset to finish. The exception
+ is other threads that were going to do cache flush---they'll wait
+ till the end of a flush operation.
*/
pthread_mutex_t structure_guard_mutex;
byte *cache; // cache memory
@@ -358,6 +369,7 @@ protected:
If query is cacheable return number tables in query
(query without tables not cached)
*/
+ static
TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query,
LEX *lex, TABLE_LIST *tables_used,
uint8 *tables_type);
@@ -410,6 +422,7 @@ protected:
void destroy();
+ friend void query_cache_init_query(NET *net);
friend void query_cache_insert(NET *net, const char *packet, ulong length);
friend void query_cache_end_of_result(THD *thd);
friend void query_cache_abort(NET *net);
@@ -435,6 +448,8 @@ protected:
extern Query_cache query_cache;
extern TYPELIB query_cache_type_typelib;
+void query_cache_init_query(NET *net);
+void query_cache_insert(NET *net, const char *packet, ulong length);
void query_cache_end_of_result(THD *thd);
void query_cache_abort(NET *net);