1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Bug#38551 query cache can still consume [very little] cpu time even when it is off.

When the query cache is disabled, the server shouldn't attempt to take the 
query cache mutex.
                             
By using the command line option --query_cache_type=0, the user can disable
   
(backport from mysql-pe)


mysql-test/t/query_cache_disabled-master.opt:
  * added test case for bug38551
mysql-test/t/query_cache_disabled.test:
  * added test case for bug38551
sql/set_var.cc:
  * Added before-trigger to verify that query_cache_type wasn't turned off or on during
  runtime.
sql/set_var.h:
  * Changed order on how the enumeration is processed. By first projecting the
  character representation of the variable to a temporary integer we can have
  one function instead of two to check if the value is valid.
sql/share/errmsg-utf8.txt:
  * Added error message for query cache disabled state
sql/sql_cache.cc:
  * If the query cache is disabled at start up, shorten the execution path and avoid
  grabbing the query cache mutex each time the invalidate interface methods are called.
sql/sql_cache.h:
  * Added new methods to set the query cache into a disabled state.
This commit is contained in:
Kristofer Pettersson
2009-10-29 12:19:36 +01:00
parent 42cdc4df8f
commit ddcdacb297
7 changed files with 124 additions and 24 deletions

View File

@ -286,6 +286,7 @@ functions:
if (and only if) this query has a registered result set writer
(thd->net.query_cache_query).
4. Query_cache::invalidate
Query_cache::invalidate_locked_for_write
- Called from various places to invalidate query cache based on data-
base, table and myisam file name. During an on going invalidation
the query cache is temporarily disabled.
@ -851,7 +852,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls,
DBUG_ENTER("Query_cache::insert");
/* See the comment on double-check locking usage above. */
if (query_cache_tls->first_query_block == NULL)
if (is_disabled() || query_cache_tls->first_query_block == NULL)
DBUG_VOID_RETURN;
DBUG_EXECUTE_IF("wait_in_query_cache_insert",
@ -913,7 +914,7 @@ Query_cache::abort(Query_cache_tls *query_cache_tls)
THD *thd= current_thd;
/* See the comment on double-check locking usage above. */
if (query_cache_tls->first_query_block == NULL)
if (is_disabled() || query_cache_tls->first_query_block == NULL)
DBUG_VOID_RETURN;
if (try_lock())
@ -1055,7 +1056,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)) +
@ -1362,8 +1363,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
See also a note on double-check locking usage above.
*/
if (thd->locked_tables || thd->variables.query_cache_type == 0 ||
query_cache_size == 0)
if (is_disabled() || thd->locked_tables ||
thd->variables.query_cache_type == 0 || query_cache_size == 0)
goto err;
if (!thd->lex->safe_to_cache_query)
@ -1669,6 +1670,8 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (table list)");
if (is_disabled())
DBUG_VOID_RETURN;
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
@ -1699,6 +1702,9 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
{
DBUG_ENTER("Query_cache::invalidate (changed table list)");
if (is_disabled())
DBUG_VOID_RETURN;
THD *thd= current_thd;
for (; tables_used; tables_used= tables_used->next)
{
@ -1724,8 +1730,11 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
*/
void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
{
THD *thd= current_thd;
DBUG_ENTER("Query_cache::invalidate_locked_for_write");
if (is_disabled())
DBUG_VOID_RETURN;
THD *thd= current_thd;
for (; tables_used; tables_used= tables_used->next_local)
{
thd_proc_info(thd, "invalidating query cache entries (table)");
@ -1746,7 +1755,9 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (table)");
if (is_disabled())
DBUG_VOID_RETURN;
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions &&
@ -1763,6 +1774,8 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (key)");
if (is_disabled())
DBUG_VOID_RETURN;
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
@ -1781,9 +1794,12 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
void Query_cache::invalidate(char *db)
{
bool restart= FALSE;
DBUG_ENTER("Query_cache::invalidate (db)");
if (is_disabled())
DBUG_VOID_RETURN;
bool restart= FALSE;
/*
Lock the query cache and queue all invalidation attempts to avoid
the risk of a race between invalidation, cache inserts and flushes.
@ -1868,6 +1884,9 @@ void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
void Query_cache::flush()
{
DBUG_ENTER("Query_cache::flush");
if (is_disabled())
DBUG_VOID_RETURN;
DBUG_EXECUTE_IF("wait_in_query_cache_flush1",
debug_wait_for_kill("wait_in_query_cache_flush1"););
@ -1899,6 +1918,9 @@ void Query_cache::pack(ulong join_limit, uint iteration_limit)
{
DBUG_ENTER("Query_cache::pack");
if (is_disabled())
DBUG_VOID_RETURN;
/*
If the entire qc is being invalidated we can bail out early
instead of waiting for the lock.
@ -1956,6 +1978,15 @@ void Query_cache::init()
pthread_cond_init(&COND_cache_status_changed, NULL);
m_cache_lock_status= Query_cache::UNLOCKED;
initialized = 1;
/*
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)
query_cache.disable_query_cache();
DBUG_VOID_RETURN;
}
@ -4660,3 +4691,4 @@ err2:
#endif /* DBUG_OFF */
#endif /*HAVE_QUERY_CACHE*/