Bug #21074 Large query_cache freezes mysql server sporadically under heavy load
Invaldating a subset of a sufficiently large query cache can take a long time. During this time the server is efficiently frozen and no other operation can be executed. This patch addresses this problem by setting a time limit on how long time a dictionary access request can take before giving up on the attempt. This patch does not work for query cache invalidations issued by DROP, ALTER or RENAME TABLE operations.
This commit is contained in:
parent
889b4ebcee
commit
f5ecb35e6c
@ -1023,6 +1023,13 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
||||
Query_cache_block_table *block_table, *block_table_end;
|
||||
ulong tot_length;
|
||||
Query_cache_query_flags flags;
|
||||
const uint spin_treshold= 50000;
|
||||
const double lock_time_treshold= 0.1; /* Time in seconds */
|
||||
uint spin_count= 0;
|
||||
int lock_status= 0;
|
||||
ulong new_time= 0;
|
||||
ulong stop_time= 0;
|
||||
|
||||
DBUG_ENTER("Query_cache::send_result_to_client");
|
||||
|
||||
/*
|
||||
@ -1069,7 +1076,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
||||
}
|
||||
}
|
||||
|
||||
STRUCT_LOCK(&structure_guard_mutex);
|
||||
stop_time= my_clock()+(ulong)lock_time_treshold*CLOCKS_PER_SEC;
|
||||
while ((lock_status= pthread_mutex_trylock(&structure_guard_mutex)) == EBUSY
|
||||
&& spin_count < spin_treshold
|
||||
&& new_time < stop_time)
|
||||
{
|
||||
spin_count++;
|
||||
if (spin_count%5)
|
||||
new_time= my_clock();
|
||||
pthread_yield();
|
||||
}
|
||||
|
||||
if (lock_status != 0)
|
||||
{
|
||||
/*
|
||||
Query cache is too busy doing something else.
|
||||
Fall back on ordinary statement execution. We also mark this
|
||||
query as unsafe to cache because otherwise this thread will
|
||||
still be halted when the result set is stored to the cache.
|
||||
*/
|
||||
thd->lex->safe_to_cache_query= FALSE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (query_cache_size == 0 || flush_in_progress)
|
||||
{
|
||||
DBUG_PRINT("qcache", ("query cache disabled"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user