Commit 54807084 authored by unknown's avatar unknown

- This patch addesses the performance issues with invalidating the entire

  cache by changing the behavior of the query cache resize-method.
- set query_cache_size=<new_size>; is significantly faster than RESET QUERY
  CACHE as it simply destroys and recreates the query cache, whereas
  RESET QUERY CACHE keeps its internal structure aligned with server 
  load profile.


sql/set_var.cc:
  Refactored behavior of function. Instead of setting the global variable
  from within the class method scope we return the new cache size as a 
  result of the method call.
sql/sql_cache.cc:
  - Changed behavior of resize-method. Now, the cache will be cleared as one
    single block of data instead of an iteration over all cached statements.
parent d4744eb9
...@@ -1275,12 +1275,19 @@ static void fix_net_retry_count(THD *thd __attribute__((unused)), ...@@ -1275,12 +1275,19 @@ static void fix_net_retry_count(THD *thd __attribute__((unused)),
static void fix_query_cache_size(THD *thd, enum_var_type type) static void fix_query_cache_size(THD *thd, enum_var_type type)
{ {
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
ulong requested= query_cache_size; ulong new_cache_size= query_cache.resize(query_cache_size);
query_cache.resize(query_cache_size);
if (requested != query_cache_size) /*
Note: query_cache_size is a global variable reflecting the
requested cache size. See also query_cache_size_arg
*/
if (query_cache_size != new_cache_size)
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE), ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
requested, query_cache_size); query_cache_size, new_cache_size);
query_cache_size= new_cache_size;
#endif #endif
} }
......
...@@ -632,7 +632,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length) ...@@ -632,7 +632,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
DUMP(&query_cache); DUMP(&query_cache);
BLOCK_LOCK_WR(query_block); BLOCK_LOCK_WR(query_block);
DBUG_PRINT("qcache", ("insert packet %lu bytes long",length)); DBUG_PRINT("qcache", ("insert parequestedcket %lu bytes long",length));
/* /*
On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be On success STRUCT_UNLOCK(&query_cache.structure_guard_mutex) will be
...@@ -799,12 +799,26 @@ ulong Query_cache::resize(ulong query_cache_size_arg) ...@@ -799,12 +799,26 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size, DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size,
query_cache_size_arg)); query_cache_size_arg));
DBUG_ASSERT(initialized); DBUG_ASSERT(initialized);
STRUCT_LOCK(&structure_guard_mutex); STRUCT_LOCK(&structure_guard_mutex);
while (flush_in_progress)
pthread_cond_wait(&COND_flush_finished, &structure_guard_mutex);
flush_in_progress= TRUE;
STRUCT_UNLOCK(&structure_guard_mutex);
free_cache(); free_cache();
query_cache_size= query_cache_size_arg; query_cache_size= query_cache_size_arg;
::query_cache_size= init_cache(); ulong new_query_cache_size= init_cache();
DBUG_EXECUTE("check_querycache",check_integrity(0););
STRUCT_LOCK(&structure_guard_mutex);
flush_in_progress= FALSE;
pthread_cond_signal(&COND_flush_finished);
STRUCT_UNLOCK(&structure_guard_mutex); STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_RETURN(::query_cache_size);
DBUG_RETURN(new_query_cache_size);
} }
...@@ -1575,6 +1589,7 @@ ulong Query_cache::init_cache() ...@@ -1575,6 +1589,7 @@ ulong Query_cache::init_cache()
int align; int align;
DBUG_ENTER("Query_cache::init_cache"); DBUG_ENTER("Query_cache::init_cache");
approx_additional_data_size = (sizeof(Query_cache) + approx_additional_data_size = (sizeof(Query_cache) +
sizeof(gptr)*(def_query_hash_size+ sizeof(gptr)*(def_query_hash_size+
def_table_hash_size)); def_table_hash_size));
...@@ -1753,58 +1768,28 @@ void Query_cache::make_disabled() ...@@ -1753,58 +1768,28 @@ void Query_cache::make_disabled()
mem_bin_num= mem_bin_steps= 0; mem_bin_num= mem_bin_steps= 0;
queries_in_cache= 0; queries_in_cache= 0;
first_block= 0; first_block= 0;
total_blocks= 0;
tables_blocks= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* /**
free_cache() - free all resources allocated by the cache. @class Query_cache
@brief Free all resources allocated by the cache.
SYNOPSIS @details This function frees all resources allocated by the cache. You
free_cache() have to call init_cache() before using the cache again. This function requires
the structure_guard_mutex to be locked.
DESCRIPTION
This function frees all resources allocated by the cache. You
have to call init_cache() before using the cache again.
*/ */
void Query_cache::free_cache() void Query_cache::free_cache()
{ {
DBUG_ENTER("Query_cache::free_cache"); DBUG_ENTER("Query_cache::free_cache");
if (query_cache_size > 0)
flush_cache();
/*
There may be two free_cache() calls in progress, because we
release 'structure_guard_mutex' in flush_cache(). When the second
flush_cache() wakes up from the wait on 'COND_flush_finished', the
first call to free_cache() has done its job. So we have to test
'query_cache_size > 0' the second time to see if the cache wasn't
reset by other thread, or if it was reset and was re-enabled then.
If the cache was reset, then we have nothing to do here.
*/
if (query_cache_size > 0)
{
#ifndef DBUG_OFF
if (bins[0].free_blocks == 0)
{
wreck(__LINE__,"no free memory found in (bins[0].free_blocks");
DBUG_VOID_RETURN;
}
#endif
/* Becasue we did a flush, all cache memory must be in one this block */ my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
bins[0].free_blocks->destroy(); make_disabled();
total_blocks--; hash_free(&queries);
#ifndef DBUG_OFF hash_free(&tables);
if (free_memory != query_cache_size)
DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
free_memory , query_cache_size));
#endif
my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
make_disabled();
hash_free(&queries);
hash_free(&tables);
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment