Commit f1e0cffb authored by Mikael Ronstrom's avatar Mikael Ronstrom

Patch to fix bug#38551

parent 772cdf00
......@@ -3448,6 +3448,19 @@ You should consider changing lower_case_table_names to 1 or 2",
files_charset_info :
&my_charset_bin);
/*
If we explicitly turn off query cache from the command line query cache will
be disabled for the reminder of the server life time. This is because we
want to avoid locking the QC specific mutex if query cache isn't going to
be used.
*/
if (global_system_variables.query_cache_type == 0)
{
have_query_cache= SHOW_OPTION_NO;
query_cache.disable_query_cache();
}
return 0;
}
......@@ -6672,12 +6685,10 @@ The minimum value for this variable is 4096.",
(uchar**) &query_cache_min_res_unit, (uchar**) &query_cache_min_res_unit,
0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
0, ULONG_MAX, 0, 1, 0},
#endif /*HAVE_QUERY_CACHE*/
{"query_cache_size", OPT_QUERY_CACHE_SIZE,
"The memory allocated to store results from old queries.",
(uchar**) &query_cache_size, (uchar**) &query_cache_size, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
#ifdef HAVE_QUERY_CACHE
{"query_cache_type", OPT_QUERY_CACHE_TYPE,
"0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT SQL_CACHE ... queries.",
(uchar**) &global_system_variables.query_cache_type,
......
......@@ -670,7 +670,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
DBUG_ENTER("query_cache_insert");
/* See the comment on double-check locking usage above. */
if (net->query_cache_query == 0)
if (query_cache.is_disabled() || net->query_cache_query == 0)
DBUG_VOID_RETURN;
DBUG_EXECUTE_IF("wait_in_query_cache_insert",
......@@ -778,7 +778,7 @@ void query_cache_end_of_result(THD *thd)
DBUG_ENTER("query_cache_end_of_result");
/* See the comment on double-check locking usage above. */
if (thd->net.query_cache_query == 0)
if (query_cache.is_disabled() || thd->net.query_cache_query == 0)
DBUG_VOID_RETURN;
if (thd->killed)
......@@ -891,7 +891,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
def_table_hash_size(ALIGN_SIZE(def_table_hash_size_arg)),
initialized(0)
initialized(0),m_query_cache_is_disabled(FALSE)
{
ulong min_needed= (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_block_table)) +
......@@ -978,7 +978,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
See also a note on double-check locking usage above.
*/
if (thd->locked_tables || query_cache_size == 0)
if (m_query_cache_is_disabled || thd->locked_tables || query_cache_size == 0)
DBUG_VOID_RETURN;
uint8 tables_type= 0;
......@@ -1161,14 +1161,18 @@ end:
Check if the query is in the cache. If it was cached, send it
to the user.
RESULTS
1 Query was not cached.
0 The query was cached and user was sent the result.
-1 The query was cached but we didn't have rights to use it.
No error is sent to the client yet.
@param thd Pointer to the thread handler
@param sql A pointer to the sql statement *
@param query_length Length of the statement in characters
NOTE
This method requires that sql points to allocated memory of size:
@return status code
@retval 1 Query was not cached.
@retval 0 The query was cached and user was sent the result.
@retval -1 The query was cached but we didn't have rights to use it.
In case of -1, no error is sent to the client.
*) The buffer must be allocated memory of size:
tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
*/
......@@ -1183,6 +1187,9 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_query_flags flags;
DBUG_ENTER("Query_cache::send_result_to_client");
if (m_query_cache_is_disabled)
DBUG_RETURN(0);
/*
Testing 'query_cache_size' without a lock here is safe: the thing
we may loose is that the query won't be served from cache, but we
......@@ -2530,7 +2537,17 @@ void Query_cache::invalidate_table(THD *thd, TABLE *table)
void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length)
{
bool interrupt;
if (m_query_cache_is_disabled)
return;
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size == 0)
{
STRUCT_UNLOCK(&structure_guard_mutex);
return;
}
wait_while_table_flush_is_in_progress(&interrupt);
if (interrupt)
{
......
......@@ -279,6 +279,8 @@ private:
Cache_status m_cache_status;
bool m_query_cache_is_disabled;
void free_query_internal(Query_cache_block *point);
void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length);
......@@ -437,6 +439,14 @@ protected:
/* register query in cache */
void store_query(THD *thd, TABLE_LIST *used_tables);
/**
At startup the user has an option to disable the query cache
to avoid locking the structure_guard_mutex.
This option is enabled by explicitly setting query_cache_type=OFF
in the command line.
*/
void disable_query_cache(void) { m_query_cache_is_disabled= TRUE; }
/*
Check if the query is in the cache and if this is true send the
data to client.
......@@ -469,6 +479,8 @@ protected:
friend void query_cache_end_of_result(THD *thd);
friend void query_cache_abort(NET *net);
bool is_disabled(void) { return m_query_cache_is_disabled; }
bool is_flushing(void)
{
return (m_cache_status != Query_cache::NO_FLUSH_IN_PROGRESS);
......
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