From a5f8ce91bfe1cc1cef3d70346c346cd48b100eb4 Mon Sep 17 00:00:00 2001 From: Roberto Spadim Date: Mon, 22 Sep 2014 18:22:38 -0300 Subject: [PATCH 1/5] Only check query cache queries with SQL_CACHE when using DEMAND query cache --- sql/sql_cache.cc | 57 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index cf68ba369978e..5f271526daf9c 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -766,6 +766,36 @@ void Query_cache::unlock(void) DBUG_VOID_RETURN; } +/** + Helper function for determine if a SELECT statement has a SQL_CACHE + directive. + + @param sql A pointer to the first white space character after SELECT + + @return + @retval TRUE The character string contains SQL_CACHE + @retval FALSE No directive found. +*/ + +static bool has_cache_directive(const char *sql) +{ + while (is_white_space(*sql)) + sql++; + + if (my_toupper(system_charset_info, sql[0]) == 'S' && + my_toupper(system_charset_info, sql[1]) == 'Q' && + my_toupper(system_charset_info, sql[2]) == 'L' && + my_toupper(system_charset_info, sql[3]) == '_' && + my_toupper(system_charset_info, sql[4]) == 'C' && + my_toupper(system_charset_info, sql[5]) == 'A' && + my_toupper(system_charset_info, sql[6]) == 'C' && + my_toupper(system_charset_info, sql[7]) == 'H' && + my_toupper(system_charset_info, sql[8]) == 'E' && + my_isspace(system_charset_info, sql[9])) + return TRUE; + + return FALSE; +} /** Helper function for determine if a SELECT statement has a SQL_NO_CACHE @@ -1817,14 +1847,27 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) goto err; } - if ((sql_end - sql) > 20 && has_no_cache_directive(sql+6)) + if ((sql_end - sql) > 20) { - /* - We do not increase 'refused' statistics here since it will be done - later when the query is parsed. - */ - DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); - goto err; + if (has_no_cache_directive(sql+6)) + { + /* + We do not increase 'refused' statistics here since it will be done + later when the query is parsed. + */ + DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); + goto err; + } + if (thd->variables.query_cache_type==2 && !has_cache_directive(sql+6, sql_end)) + { + /* + We do not increase 'refused' statistics here since it will be done + later when the query is parsed. + */ + DBUG_PRINT("qcache", + ("The statement don't have a SQL_CACHE directive when query_cache_type=DEMAND")); + goto err; + } } { /* From 612621cf3aaaf6d6cc43ca1bac31b6fdc79f0f47 Mon Sep 17 00:00:00 2001 From: Roberto Spadim Date: Mon, 22 Sep 2014 18:29:06 -0300 Subject: [PATCH 2/5] Remove last parameter from has_cache function --- sql/sql_cache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 5f271526daf9c..70a67e587b717 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1858,7 +1858,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); goto err; } - if (thd->variables.query_cache_type==2 && !has_cache_directive(sql+6, sql_end)) + if (thd->variables.query_cache_type==2 && !has_cache_directive(sql+6)) { /* We do not increase 'refused' statistics here since it will be done From e4f8c142ff463adf836ad03e5e1145f5b0f3b157 Mon Sep 17 00:00:00 2001 From: Roberto Spadim Date: Wed, 24 Sep 2014 00:28:29 -0300 Subject: [PATCH 3/5] check SQL_CACHE when using query_cache_type=DEMAND_PRUNE --- sql/share/errmsg-utf8.txt | 2 +- sql/sql_cache.cc | 7 ++++--- sql/sys_vars.cc | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 32cdbe138b284..2f77cfd7d0443 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6231,7 +6231,7 @@ ER_SLAVE_IGNORE_SERVER_IDS eng "The requested server id %d clashes with the slave startup option --replicate-same-server-id" ger "Die angeforderte Server-ID %d steht im Konflikt mit der Startoption --replicate-same-server-id für den Slave" ER_QUERY_CACHE_DISABLED - eng "Query cache is disabled; set query_cache_type to ON or DEMAND to enable it" + eng "Query cache is disabled; set query_cache_type to ON or DEMAND or DEMAND_PRUNE to enable it" ER_SAME_NAME_PARTITION_FIELD eng "Duplicate partition field name '%-.192s'" ger "Partitionsfeld '%-.192s' ist ein Duplikat" diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 70a67e587b717..e25145ad8d039 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1858,14 +1858,14 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); goto err; } - if (thd->variables.query_cache_type==2 && !has_cache_directive(sql+6)) + if (thd->variables.query_cache_type==3 /* DEMAND_PRUNE */ && !has_cache_directive(sql+6)) { /* We do not increase 'refused' statistics here since it will be done later when the query is parsed. */ DBUG_PRINT("qcache", - ("The statement don't have a SQL_CACHE directive when query_cache_type=DEMAND")); + ("The statement don't have a SQL_CACHE directive when query_cache_type=DEMAND_PRUNE")); goto err; } } @@ -4126,7 +4126,8 @@ Query_cache::is_cacheable(THD *thd, LEX *lex, if (thd->lex->safe_to_cache_query && (thd->variables.query_cache_type == 1 || - (thd->variables.query_cache_type == 2 && (lex->select_lex.options & + ((thd->variables.query_cache_type == 2|| + thd->variables.query_cache_type == 3) && (lex->select_lex.options & OPTION_TO_QUERY_CACHE))) && qc_is_able_to_intercept_result(thd)) { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 0c68409dd2567..ca2c18919dbc4 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2600,7 +2600,7 @@ static Sys_var_ulong Sys_query_cache_min_res_unit( BLOCK_SIZE(8), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_qcache_min_res_unit)); -static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", 0 }; +static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", "DEMAND_PRUNE", 0 }; static bool check_query_cache_type(sys_var *self, THD *thd, set_var *var) { if (query_cache.is_disable_in_progress()) @@ -2639,7 +2639,8 @@ static Sys_var_enum Sys_query_cache_type( "query_cache_type", "OFF = Don't cache or retrieve results. ON = Cache all results " "except SELECT SQL_NO_CACHE ... queries. DEMAND = Cache only " - "SELECT SQL_CACHE ... queries", + "SELECT SQL_CACHE ... queries. DEMAND_PRUNE = DEMAND , but only " + "fetch from query cache with SQL_CACHE queries", SESSION_VAR(query_cache_type), CMD_LINE(REQUIRED_ARG), query_cache_type_names, DEFAULT(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_query_cache_type), From d02181ff0ce3704033752049ed285b88638f5a43 Mon Sep 17 00:00:00 2001 From: Roberto Spadim Date: Sat, 27 Sep 2014 01:25:10 -0300 Subject: [PATCH 4/5] Instead of DEMAND_PRUNE, leave DEMAND as default, and create a DEMAND_NO_PRUNE with old features --- sql/share/errmsg-utf8.txt | 2 +- sql/sql_cache.cc | 11 ++++++----- sql/sys_vars.cc | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 2f77cfd7d0443..0f3124a6c2ae9 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6231,7 +6231,7 @@ ER_SLAVE_IGNORE_SERVER_IDS eng "The requested server id %d clashes with the slave startup option --replicate-same-server-id" ger "Die angeforderte Server-ID %d steht im Konflikt mit der Startoption --replicate-same-server-id für den Slave" ER_QUERY_CACHE_DISABLED - eng "Query cache is disabled; set query_cache_type to ON or DEMAND or DEMAND_PRUNE to enable it" + eng "Query cache is disabled; set query_cache_type to ON or DEMAND or DEMAND_NO_PRUNE to enable it" ER_SAME_NAME_PARTITION_FIELD eng "Duplicate partition field name '%-.192s'" ger "Partitionsfeld '%-.192s' ist ein Duplikat" diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index e25145ad8d039..d4be6aa8fd92a 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1858,14 +1858,15 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length) DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive")); goto err; } - if (thd->variables.query_cache_type==3 /* DEMAND_PRUNE */ && !has_cache_directive(sql+6)) + /* DEMAND, use DEMAND_NO_PUNE to avoid this check */ + if (thd->variables.query_cache_type==2 && !has_cache_directive(sql+6)) { /* We do not increase 'refused' statistics here since it will be done later when the query is parsed. */ DBUG_PRINT("qcache", - ("The statement don't have a SQL_CACHE directive when query_cache_type=DEMAND_PRUNE")); + ("The statement don't have a SQL_CACHE directive when query_cache_type=DEMAND")); goto err; } } @@ -4126,9 +4127,9 @@ Query_cache::is_cacheable(THD *thd, LEX *lex, if (thd->lex->safe_to_cache_query && (thd->variables.query_cache_type == 1 || - ((thd->variables.query_cache_type == 2|| - thd->variables.query_cache_type == 3) && (lex->select_lex.options & - OPTION_TO_QUERY_CACHE))) && + ((thd->variables.query_cache_type == 2 || /* DEMAND */ + thd->variables.query_cache_type == 3) && /* DEMAND_NO_PRUNE */ + (lex->select_lex.options & OPTION_TO_QUERY_CACHE))) && qc_is_able_to_intercept_result(thd)) { DBUG_PRINT("qcache", ("options: %lx %lx type: %u", diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index ca2c18919dbc4..49da3bcdf1b52 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2600,7 +2600,7 @@ static Sys_var_ulong Sys_query_cache_min_res_unit( BLOCK_SIZE(8), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_qcache_min_res_unit)); -static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", "DEMAND_PRUNE", 0 }; +static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", "DEMAND_NO_PRUNE", 0 }; static bool check_query_cache_type(sys_var *self, THD *thd, set_var *var) { if (query_cache.is_disable_in_progress()) From b9fa878ca1314d7610edfda78f43bc54262b03fb Mon Sep 17 00:00:00 2001 From: Roberto Spadim Date: Sat, 27 Sep 2014 01:29:33 -0300 Subject: [PATCH 5/5] Better explain what DEMAND_NO_PRUNE do --- sql/sys_vars.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 49da3bcdf1b52..e7db96d3f4a0c 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2639,8 +2639,8 @@ static Sys_var_enum Sys_query_cache_type( "query_cache_type", "OFF = Don't cache or retrieve results. ON = Cache all results " "except SELECT SQL_NO_CACHE ... queries. DEMAND = Cache only " - "SELECT SQL_CACHE ... queries. DEMAND_PRUNE = DEMAND , but only " - "fetch from query cache with SQL_CACHE queries", + "SELECT SQL_CACHE ... queries. DEMAND_NO_PRUNE = DEMAND , but allow " + "fetch query from cache previous inserted without SQL_CACHE", SESSION_VAR(query_cache_type), CMD_LINE(REQUIRED_ARG), query_cache_type_names, DEFAULT(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_query_cache_type),