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:
@ -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*/
|
||||
|
||||
|
Reference in New Issue
Block a user