Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sql/mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8212,6 +8212,7 @@ SHOW_VAR status_vars[]= {
{"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
{"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG},
{"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
{"Qcache_concurrency_refused", (char*) &query_cache.concurrency_refused, SHOW_LONG},
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
#endif /*HAVE_QUERY_CACHE*/
Expand Down
36 changes: 29 additions & 7 deletions sql/sql_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ void inline fix_local_query_cache_mode(THD *thd)
effect by another thread. This enables a quick path in execution to skip waits
when the outcome is known.

@param mode TIMEOUT the lock can abort because of a timeout
@param mode TIMEOUT_WRITE/TIMEOUT_READ the lock can abort because of a timeout
TRY the lock can abort because it is locked now
WAIT wait for lock (default)

Expand Down Expand Up @@ -643,10 +643,29 @@ bool Query_cache::try_lock(THD *thd, Cache_try_lock_mode mode)
{
mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
}
else if (mode == TIMEOUT)
else if (mode == TIMEOUT_READ || mode == TIMEOUT_WRITE)
{
struct timespec waittime;
set_timespec_nsec(waittime,(ulong)(50000000L)); /* Wait for 50 msec */
if(mode == TIMEOUT_WRITE){
if(thd->variables.query_cache_write_timeout<=0)
/* Default: wait for 50 msec (nano time value=> 50.000.000ns = 50ms) */
thd->variables.query_cache_write_timeout=50000000L;
if(thd->variables.query_cache_write_timeout>1000000000L;
/* Max value of 1s (1.000.000.000) */
thd->variables.query_cache_write_timeout=1000000000L;

set_timespec_nsec(waittime,(ulong)(thd->variables.query_cache_write_timeout));
}
else
{
if(thd->variables.query_cache_read_timeout<=0)
/* Default: wait for 50 msec (nano time value=> 50.000.000ns = 50ms) */
thd->variables.query_cache_read_timeout=50000000L;
if(thd->variables.query_cache_read_timeout>1000000000L;
/* Max value of 1s (1.000.000.000) */
thd->variables.query_cache_read_timeout=1000000000L;
set_timespec_nsec(waittime,(ulong)(thd->variables.query_cache_read_timeout));
}
int res= mysql_cond_timedwait(&COND_cache_status_changed,
&structure_guard_mutex, &waittime);
if (res == ETIMEDOUT)
Expand Down Expand Up @@ -1275,6 +1294,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
query_cache_limit(query_cache_limit_arg),
queries_in_cache(0), hits(0), inserts(0), refused(0),
total_blocks(0), lowmem_prunes(0),
concurrency_refused(0),
m_cache_status(OK),
min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
Expand Down Expand Up @@ -1474,10 +1494,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
In case the wait time can't be determined there is an upper limit which
causes try_lock() to abort with a time out.

The 'TIMEOUT' parameter indicate that the lock is allowed to timeout
The TIMEOUT_WRITE parameter indicate that the lock is allowed to timeout

*/
if (try_lock(thd, Query_cache::TIMEOUT))
if (try_lock(thd, Query_cache::TIMEOUT_WRITE))
DBUG_VOID_RETURN;
if (query_cache_size == 0)
{
Expand Down Expand Up @@ -1576,6 +1596,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
}
else
{
// Concorrency counter
concurrency_refused++;
// Another thread is processing the same query => do nothing
refused++;
unlock();
Expand Down Expand Up @@ -1853,9 +1875,9 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
disabled or if a full cache flush is in progress, the attempt to
get the lock is aborted.

The TIMEOUT parameter indicate that the lock is allowed to timeout.
The TIMEOUT_READ parameter indicate that the lock is allowed to timeout.
*/
if (try_lock(thd, Query_cache::TIMEOUT))
if (try_lock(thd, Query_cache::TIMEOUT_READ))
goto err;

if (query_cache_size == 0)
Expand Down
5 changes: 3 additions & 2 deletions sql/sql_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,8 @@ class Query_cache
ulong query_cache_size, query_cache_limit;
/* statistics */
ulong free_memory, queries_in_cache, hits, inserts, refused,
free_memory_blocks, total_blocks, lowmem_prunes;
free_memory_blocks, total_blocks, lowmem_prunes,
concurrency_refused;


private:
Expand Down Expand Up @@ -524,7 +525,7 @@ class Query_cache
static uint filename_2_table_key (char *key, const char *filename,
uint32 *db_langth);

enum Cache_try_lock_mode {WAIT, TIMEOUT, TRY};
enum Cache_try_lock_mode {WAIT, TIMEOUT_WRITE, TIMEOUT_READ, TRY};
bool try_lock(THD *thd, Cache_try_lock_mode mode= WAIT);
void lock(THD *thd);
void lock_and_suspend(void);
Expand Down
2 changes: 2 additions & 0 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ typedef struct system_variables
ulong progress_report_time;
ulong completion_type;
ulong query_cache_type;
ulong query_cache_write_timeout;
ulong query_cache_read_timeout;
ulong tx_isolation;
ulong updatable_views_with_limit;
int max_user_connections;
Expand Down
12 changes: 12 additions & 0 deletions sql/sys_vars.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2539,6 +2539,18 @@ static Sys_var_enum Sys_thread_handling(
);

#ifdef HAVE_QUERY_CACHE
static Sys_var_ulong Sys_query_cache_write_timeout(
"query_cache_write_timeout",
"Timeout in nanoseconds waiting lock in query cache insert, "
"default of 50000000 ns = 50ms",
SESSION_VAR(query_cache_write_timeout), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, 1000000000L), DEFAULT(50000000), BLOCK_SIZE(1));
static Sys_var_ulong Sys_query_cache_read_timeout(
"query_cache_read_timeout",
"Timeout in nanoseconds waiting lock in query cache fetch, "
"default of 50000000 ns = 50ms",
SESSION_VAR(query_cache_read_timeout), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, 1000000000L), DEFAULT(50000000), BLOCK_SIZE(1));
static bool check_query_cache_size(sys_var *self, THD *thd, set_var *var)
{
if (global_system_variables.query_cache_type == 0 &&
Expand Down