summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorunknown <kroki/tomash@moonlight.intranet>2006-08-22 11:47:52 +0400
committerunknown <kroki/tomash@moonlight.intranet>2006-08-22 11:47:52 +0400
commit877477f173419933f1d7c2b9e06dc7cfe925eb6e (patch)
tree6da805e8e859d377d16c5f512dfe034ba5c7ecb2 /sql/sql_class.cc
parentd8180d44b81519ee1d1db8fe79caa2a6d1d6a5eb (diff)
downloadmariadb-git-877477f173419933f1d7c2b9e06dc7cfe925eb6e.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. include/mysql_com.h: Add comment for NET::query_cache_query. sql/net_serv.cc: Use query_cache_init_query() for initialization of NET::query_cache_query if query cache is used. Do not access net->query_cache_query without a lock. sql/sql_cache.cc: Fix bug with accessing query_cache_size, Query_cache_query::wri and thd->net.query_cache_query before acquiring the lock---leave double-check locking only in safe places. Wherever we check that cache is usable (query_cache_size > 0) we now also check that flush_in_progress is false, i.e. we are not in the middle of cache flush. Add Query_cache::not_in_flush_or_wait() method and use it in Query_cache::flush_cache(), so that threads doing cache flush will wait it to finish, while other threads will bypass the cache as if it is disabled. Extract Query_cache::free_query_internal() from Query_cache::free_query(), which does not removes elements from the hash, and use it together with my_hash_reset() in Query_cache::flush_cache(). sql/sql_cache.h: Add declarations for new members and methods. Make is_cacheable() a static method. Add query_cache_init_query() function. sql/sql_class.cc: Use query_cache_init_query() for initialization of NET::query_cache_query.
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc2
1 files changed, 1 insertions, 1 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5c8bd797e7c..b33c221c7a7 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -223,7 +223,7 @@ THD::THD()
#endif
client_capabilities= 0; // minimalistic client
net.last_error[0]=0; // If error on boot
- net.query_cache_query=0; // If error on boot
+ query_cache_init_query(&net); // If error on boot
ull=0;
system_thread= cleanup_done= abort_on_warning= no_warnings_for_error= 0;
peer_port= 0; // For SHOW PROCESSLIST