summaryrefslogtreecommitdiff
path: root/sql/sql_cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_cache.cc')
-rw-r--r--sql/sql_cache.cc512
1 files changed, 294 insertions, 218 deletions
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 901ff2d8744..f605d5ae20c 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
Description of the query cache:
@@ -288,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.
@@ -328,31 +327,36 @@ TODO list:
(This could be done with almost no speed penalty)
*/
-#include "mysql_priv.h"
+#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
+#include "sql_priv.h"
+#include "sql_cache.h"
+#include "sql_parse.h" // check_table_access
+#include "tztime.h" // struct Time_zone
+#include "sql_acl.h" // SELECT_ACL
+#include "sql_base.h" // TMP_TABLE_KEY_EXTRA
+#include "debug_sync.h" // DEBUG_SYNC
#ifdef HAVE_QUERY_CACHE
#include <m_ctype.h>
#include <my_dir.h>
#include <hash.h>
#include "../storage/myisammrg/ha_myisammrg.h"
#include "../storage/myisammrg/myrg_def.h"
+#include "probes_mysql.h"
+#include "transaction.h"
#ifdef EMBEDDED_LIBRARY
#include "emb_qcache.h"
#endif
#if !defined(EXTRA_DBUG) && !defined(DBUG_OFF)
-#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
- pthread_mutex_lock(M);}
-#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
- (ulong)(M))); pthread_mutex_unlock(M);}
#define RW_WLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock 0x%lx",(ulong)(M))); \
- if (!rw_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")); \
+ if (!mysql_rwlock_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")); \
else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
#define RW_RLOCK(M) {DBUG_PRINT("lock", ("rwlock rlock 0x%lx", (ulong)(M))); \
- if (!rw_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")); \
+ if (!mysql_rwlock_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")); \
else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
#define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock unlock 0x%lx",(ulong)(M))); \
- if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")); \
+ if (!mysql_rwlock_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")); \
else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); }
#define BLOCK_LOCK_WR(B) {DBUG_PRINT("lock", ("%d LOCK_WR 0x%lx",\
__LINE__,(ulong)(B))); \
@@ -368,38 +372,10 @@ TODO list:
__LINE__,(ulong)(B)));B->query()->unlock_reading();}
#define DUMP(C) DBUG_EXECUTE("qcache", {\
(C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();})
-
-
-/**
- Causes the thread to wait in a spin lock for a query kill signal.
- This function is used by the test frame work to identify race conditions.
-
- The signal is caught and ignored and the thread is not killed.
-*/
-
-static void debug_wait_for_kill(const char *info)
-{
- DBUG_ENTER("debug_wait_for_kill");
- const char *prev_info;
- THD *thd;
- thd= current_thd;
- prev_info= thd->proc_info;
- thd->proc_info= info;
- sql_print_information("%s", info);
- while(!thd->killed)
- my_sleep(1000);
- thd->killed= THD::NOT_KILLED;
- sql_print_information("Exit debug_wait_for_kill");
- thd->proc_info= prev_info;
- DBUG_VOID_RETURN;
-}
-
#else
-#define MUTEX_LOCK(M) pthread_mutex_lock(M)
-#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
-#define RW_WLOCK(M) rw_wrlock(M)
-#define RW_RLOCK(M) rw_rdlock(M)
-#define RW_UNLOCK(M) rw_unlock(M)
+#define RW_WLOCK(M) mysql_rwlock_wrlock(M)
+#define RW_RLOCK(M) mysql_rwlock_rdlock(M)
+#define RW_UNLOCK(M) mysql_rwlock_unlock(M)
#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
#define BLOCK_LOCK_RD(B) B->query()->lock_reading()
#define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing()
@@ -407,10 +383,49 @@ static void debug_wait_for_kill(const char *info)
#define DUMP(C)
#endif
-const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND",NullS };
-TYPELIB query_cache_type_typelib=
+
+/**
+ Macro that executes the requested action at a synchronization point
+ only if the thread has a associated THD session.
+*/
+#if defined(ENABLED_DEBUG_SYNC)
+#define QC_DEBUG_SYNC(name) \
+ do { \
+ THD *thd= current_thd; \
+ if (thd) \
+ DEBUG_SYNC(thd, name); \
+ } while (0)
+#else
+#define QC_DEBUG_SYNC(name)
+#endif
+
+
+/**
+ Thread state to be used when the query cache lock needs to be acquired.
+ Sets the thread state name in the constructor, resets on destructor.
+*/
+
+struct Query_cache_wait_state
{
- array_elements(query_cache_type_names)-1,"", query_cache_type_names, NULL
+ THD *m_thd;
+ const char *m_proc_info;
+
+ Query_cache_wait_state(THD *thd, const char *func,
+ const char *file, unsigned int line)
+ : m_thd(thd),
+ m_proc_info(NULL)
+ {
+ if (m_thd)
+ m_proc_info= set_thd_proc_info(m_thd,
+ "Waiting for query cache lock",
+ func, file, line);
+ }
+
+ ~Query_cache_wait_state()
+ {
+ if (m_thd)
+ set_thd_proc_info(m_thd, m_proc_info, NULL, NULL, 0);
+ }
};
@@ -435,16 +450,17 @@ TYPELIB query_cache_type_typelib=
bool Query_cache::try_lock(bool use_timeout)
{
bool interrupt= FALSE;
+ THD *thd= current_thd;
+ Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
DBUG_ENTER("Query_cache::try_lock");
- pthread_mutex_lock(&structure_guard_mutex);
+ mysql_mutex_lock(&structure_guard_mutex);
while (1)
{
if (m_cache_lock_status == Query_cache::UNLOCKED)
{
m_cache_lock_status= Query_cache::LOCKED;
#ifndef DBUG_OFF
- THD *thd= current_thd;
if (thd)
m_cache_lock_thread_id= thd->thread_id;
#endif
@@ -470,8 +486,8 @@ bool Query_cache::try_lock(bool use_timeout)
{
struct timespec waittime;
set_timespec_nsec(waittime,(ulong)(50000000L)); /* Wait for 50 msec */
- int res= pthread_cond_timedwait(&COND_cache_status_changed,
- &structure_guard_mutex,&waittime);
+ int res= mysql_cond_timedwait(&COND_cache_status_changed,
+ &structure_guard_mutex, &waittime);
if (res == ETIMEDOUT)
{
interrupt= TRUE;
@@ -480,11 +496,11 @@ bool Query_cache::try_lock(bool use_timeout)
}
else
{
- pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
}
}
}
- pthread_mutex_unlock(&structure_guard_mutex);
+ mysql_mutex_unlock(&structure_guard_mutex);
DBUG_RETURN(interrupt);
}
@@ -503,20 +519,21 @@ bool Query_cache::try_lock(bool use_timeout)
void Query_cache::lock_and_suspend(void)
{
+ THD *thd= current_thd;
+ Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
DBUG_ENTER("Query_cache::lock_and_suspend");
- pthread_mutex_lock(&structure_guard_mutex);
+ mysql_mutex_lock(&structure_guard_mutex);
while (m_cache_lock_status != Query_cache::UNLOCKED)
- pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
m_cache_lock_status= Query_cache::LOCKED_NO_WAIT;
#ifndef DBUG_OFF
- THD *thd= current_thd;
if (thd)
m_cache_lock_thread_id= thd->thread_id;
#endif
/* Wake up everybody, a whole cache flush is starting! */
- pthread_cond_broadcast(&COND_cache_status_changed);
- pthread_mutex_unlock(&structure_guard_mutex);
+ mysql_cond_broadcast(&COND_cache_status_changed);
+ mysql_mutex_unlock(&structure_guard_mutex);
DBUG_VOID_RETURN;
}
@@ -531,18 +548,19 @@ void Query_cache::lock_and_suspend(void)
void Query_cache::lock(void)
{
+ THD *thd= current_thd;
+ Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
DBUG_ENTER("Query_cache::lock");
- pthread_mutex_lock(&structure_guard_mutex);
+ mysql_mutex_lock(&structure_guard_mutex);
while (m_cache_lock_status != Query_cache::UNLOCKED)
- pthread_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
+ mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
m_cache_lock_status= Query_cache::LOCKED;
#ifndef DBUG_OFF
- THD *thd= current_thd;
if (thd)
m_cache_lock_thread_id= thd->thread_id;
#endif
- pthread_mutex_unlock(&structure_guard_mutex);
+ mysql_mutex_unlock(&structure_guard_mutex);
DBUG_VOID_RETURN;
}
@@ -555,7 +573,7 @@ void Query_cache::lock(void)
void Query_cache::unlock(void)
{
DBUG_ENTER("Query_cache::unlock");
- pthread_mutex_lock(&structure_guard_mutex);
+ mysql_mutex_lock(&structure_guard_mutex);
#ifndef DBUG_OFF
THD *thd= current_thd;
if (thd)
@@ -565,8 +583,8 @@ void Query_cache::unlock(void)
m_cache_lock_status == Query_cache::LOCKED_NO_WAIT);
m_cache_lock_status= Query_cache::UNLOCKED;
DBUG_PRINT("Query_cache",("Sending signal"));
- pthread_cond_signal(&COND_cache_status_changed);
- pthread_mutex_unlock(&structure_guard_mutex);
+ mysql_cond_signal(&COND_cache_status_changed);
+ mysql_mutex_unlock(&structure_guard_mutex);
DBUG_VOID_RETURN;
}
@@ -735,7 +753,7 @@ inline void Query_cache_query::lock_writing()
my_bool Query_cache_query::try_lock_writing()
{
DBUG_ENTER("Query_cache_block::try_lock_writing");
- if (rw_trywrlock(&lock)!=0)
+ if (mysql_rwlock_trywrlock(&lock) != 0)
{
DBUG_PRINT("info", ("can't lock rwlock"));
DBUG_RETURN(0);
@@ -767,7 +785,7 @@ void Query_cache_query::init_n_lock()
{
DBUG_ENTER("Query_cache_query::init_n_lock");
res=0; wri = 0; len = 0;
- my_rwlock_init(&lock, NULL);
+ mysql_rwlock_init(key_rwlock_query_cache_query_lock, &lock);
lock_writing();
DBUG_PRINT("qcache", ("inited & locked query for block 0x%lx",
(long) (((uchar*) this) -
@@ -787,7 +805,7 @@ void Query_cache_query::unlock_n_destroy()
active semaphore
*/
this->unlock_writing();
- rwlock_destroy(&lock);
+ mysql_rwlock_destroy(&lock);
DBUG_VOID_RETURN;
}
@@ -813,19 +831,20 @@ uchar *query_cache_query_get_key(const uchar *record, size_t *length,
Note on double-check locking (DCL) usage.
Below, in query_cache_insert(), query_cache_abort() and
- query_cache_end_of_result() we use what is called double-check
- locking (DCL) for NET::query_cache_query. I.e. we test it first
- without a lock, and, if positive, test again under the lock.
+ Query_cache::end_of_result() we use what is called double-check
+ locking (DCL) for Query_cache_tls::first_query_block.
+ I.e. we test it first without a lock, and, if positive, test again
+ under the lock.
- This means that if we see 'NET::query_cache_query == 0' without a
+ This means that if we see 'first_query_block == 0' without a
lock we will skip the operation. But this is safe here: when we
started to cache a query, we called Query_cache::store_query(), and
- NET::query_cache_query was set to non-zero in this thread (and the
+ 'first_query_block' was set to non-zero in this thread (and the
thread always sees results of its memory operations, mutex or not).
- If later we see 'NET::query_cache_query == 0' without locking a
+ If later we see 'first_query_block == 0' without locking a
mutex, that may only mean that some other thread have reset it by
invalidating the query. Skipping the operation in this case is the
- right thing to do, as NET::query_cache_query won't get non-zero for
+ right thing to do, as first_query_block won't get non-zero for
this query again.
See also comments in Query_cache::store_query() and
@@ -834,56 +853,69 @@ uchar *query_cache_query_get_key(const uchar *record, size_t *length,
NOTE, however, that double-check locking is not applicable in
'invalidate' functions, as we may erroneously skip invalidation,
because the thread doing invalidation may never see non-zero
- NET::query_cache_query.
+ 'first_query_block'.
*/
-void query_cache_init_query(NET *net)
+/**
+ libmysql convenience wrapper to insert data into query cache.
+*/
+void query_cache_insert(const char *packet, ulong length,
+ unsigned pkt_nr)
{
+ THD *thd= current_thd;
+
/*
- It is safe to initialize 'NET::query_cache_query' without a lock
- here, because before it will be accessed from different threads it
- will be set in this thread under a lock, and access from the same
- thread is always safe.
+ Current_thd can be NULL when a new connection is immediately ended
+ due to "Too many connections". thd->store_globals() has not been
+ called at this time and hence my_pthread_setspecific_ptr(THR_THD,
+ this) has not been called for this thread.
*/
- net->query_cache_query= 0;
+
+ if (!thd)
+ return;
+
+ query_cache.insert(&thd->query_cache_tls,
+ packet, length,
+ pkt_nr);
}
-/*
+/**
Insert the packet into the query cache.
*/
-void query_cache_insert(NET *net, const char *packet, ulong length)
+void
+Query_cache::insert(Query_cache_tls *query_cache_tls,
+ const char *packet, ulong length,
+ unsigned pkt_nr)
{
- DBUG_ENTER("query_cache_insert");
+ DBUG_ENTER("Query_cache::insert");
/* See the comment on double-check locking usage above. */
- if (net->query_cache_query == 0)
+ if (is_disabled() || query_cache_tls->first_query_block == NULL)
DBUG_VOID_RETURN;
- DBUG_EXECUTE_IF("wait_in_query_cache_insert",
- debug_wait_for_kill("wait_in_query_cache_insert"); );
+ QC_DEBUG_SYNC("wait_in_query_cache_insert");
- if (query_cache.try_lock())
+ if (try_lock())
DBUG_VOID_RETURN;
- Query_cache_block *query_block= (Query_cache_block*)net->query_cache_query;
- if (!query_block)
+ Query_cache_block *query_block = query_cache_tls->first_query_block;
+ if (query_block == NULL)
{
/*
We lost the writer and the currently processed query has been
invalidated; there is nothing left to do.
*/
- query_cache.unlock();
+ unlock();
DBUG_VOID_RETURN;
}
-
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query();
Query_cache_block *result= header->result();
- DUMP(&query_cache);
+ DUMP(this);
DBUG_PRINT("qcache", ("insert packet %lu bytes long",length));
/*
@@ -891,8 +923,8 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
still need structure_guard_mutex to free the query, and therefore unlock
it later in this function.
*/
- if (!query_cache.append_result_data(&result, length, (uchar*) packet,
- query_block))
+ if (!append_result_data(&result, length, (uchar*) packet,
+ query_block))
{
DBUG_PRINT("warning", ("Can't append data"));
header->result(result);
@@ -901,80 +933,83 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
query_cache.free_query(query_block);
query_cache.refused++;
// append_result_data no success => we need unlock
- query_cache.unlock();
+ unlock();
DBUG_VOID_RETURN;
}
header->result(result);
- header->last_pkt_nr= net->pkt_nr;
+ header->last_pkt_nr= pkt_nr;
BLOCK_UNLOCK_WR(query_block);
- DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+ DBUG_EXECUTE("check_querycache",check_integrity(0););
DBUG_VOID_RETURN;
}
-void query_cache_abort(NET *net)
+void
+Query_cache::abort(Query_cache_tls *query_cache_tls)
{
DBUG_ENTER("query_cache_abort");
THD *thd= current_thd;
/* See the comment on double-check locking usage above. */
- if (net->query_cache_query == 0)
+ if (is_disabled() || query_cache_tls->first_query_block == NULL)
DBUG_VOID_RETURN;
- if (query_cache.try_lock())
+ if (try_lock())
DBUG_VOID_RETURN;
/*
While we were waiting another thread might have changed the status
of the writer. Make sure the writer still exists before continue.
*/
- Query_cache_block *query_block= ((Query_cache_block*)
- net->query_cache_query);
+ Query_cache_block *query_block= query_cache_tls->first_query_block;
if (query_block)
{
thd_proc_info(thd, "storing result in query cache");
- DUMP(&query_cache);
+ DUMP(this);
BLOCK_LOCK_WR(query_block);
// The following call will remove the lock on query_block
- query_cache.free_query(query_block);
- net->query_cache_query= 0;
- DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+ free_query(query_block);
+ query_cache_tls->first_query_block= NULL;
+ DBUG_EXECUTE("check_querycache", check_integrity(1););
}
- query_cache.unlock();
+ unlock();
+
DBUG_VOID_RETURN;
}
-void query_cache_end_of_result(THD *thd)
+void Query_cache::end_of_result(THD *thd)
{
Query_cache_block *query_block;
- DBUG_ENTER("query_cache_end_of_result");
+ Query_cache_tls *query_cache_tls= &thd->query_cache_tls;
+ ulonglong limit_found_rows= thd->limit_found_rows;
+ 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_tls->first_query_block == NULL)
DBUG_VOID_RETURN;
/* Ensure that only complete results are cached. */
- DBUG_ASSERT(thd->main_da.is_eof());
+ DBUG_ASSERT(thd->stmt_da->is_eof());
if (thd->killed)
{
- query_cache_abort(&thd->net);
+ query_cache_abort(&thd->query_cache_tls);
DBUG_VOID_RETURN;
}
#ifdef EMBEDDED_LIBRARY
- query_cache_insert(&thd->net, (char*)thd,
- emb_count_querycache_size(thd));
+ insert(query_cache_tls, (char*)thd,
+ emb_count_querycache_size(thd), 0);
#endif
- if (query_cache.try_lock())
+ if (try_lock())
DBUG_VOID_RETURN;
- query_block= ((Query_cache_block*) thd->net.query_cache_query);
+ query_block= query_cache_tls->first_query_block;
if (query_block)
{
/*
@@ -983,7 +1018,7 @@ void query_cache_end_of_result(THD *thd)
block, the writer should be dropped.
*/
thd_proc_info(thd, "storing result in query cache");
- DUMP(&query_cache);
+ DUMP(this);
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query();
Query_cache_block *last_result_block;
@@ -1000,8 +1035,8 @@ void query_cache_end_of_result(THD *thd)
and removed from QC.
*/
DBUG_ASSERT(0);
- query_cache.free_query(query_block);
- query_cache.unlock();
+ free_query(query_block);
+ unlock();
DBUG_VOID_RETURN;
}
last_result_block= header->result()->prev;
@@ -1010,17 +1045,17 @@ void query_cache_end_of_result(THD *thd)
if (last_result_block->length >= query_cache.min_allocation_unit + len)
query_cache.split_block(last_result_block,len);
- header->found_rows(current_thd->limit_found_rows);
+ header->found_rows(limit_found_rows);
header->result()->type= Query_cache_block::RESULT;
/* Drop the writer. */
header->writer(0);
- thd->net.query_cache_query= 0;
+ query_cache_tls->first_query_block= NULL;
BLOCK_UNLOCK_WR(query_block);
- DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
-
+ DBUG_EXECUTE("check_querycache", check_integrity(1););
}
- query_cache.unlock();
+
+ unlock();
DBUG_VOID_RETURN;
}
@@ -1055,7 +1090,7 @@ Query_cache::Query_cache(ulong query_cache_limit_arg,
:query_cache_size(0),
query_cache_limit(query_cache_limit_arg),
queries_in_cache(0), hits(0), inserts(0), refused(0),
- total_blocks(0), lowmem_prunes(0),
+ total_blocks(0), lowmem_prunes(0), m_query_cache_is_disabled(FALSE),
min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
@@ -1098,7 +1133,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
Drop the writer; this will cancel any attempts to store
the processed statement associated with this writer.
*/
- query->writer()->query_cache_query= 0;
+ query->writer()->first_query_block= NULL;
query->writer(0);
refused++;
}
@@ -1140,7 +1175,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 (thd->locked_tables_mode || query_cache_size == 0)
DBUG_VOID_RETURN;
uint8 tables_type= 0;
@@ -1160,10 +1195,12 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
protocol (COM_EXECUTE) cannot be served to statements asking for results
in the text protocol (COM_QUERY) and vice-versa.
*/
- flags.result_in_binary_protocol= (unsigned int) thd->protocol->type();
+ flags.protocol_type= (unsigned int) thd->protocol->type();
+ /* PROTOCOL_LOCAL results are not cached. */
+ DBUG_ASSERT(flags.protocol_type != (unsigned int) Protocol::PROTOCOL_LOCAL);
flags.more_results_exists= test(thd->server_status &
SERVER_MORE_RESULTS_EXISTS);
- flags.in_trans= test(thd->server_status & SERVER_STATUS_IN_TRANS);
+ flags.in_trans= thd->in_active_multi_stmt_transaction();
flags.autocommit= test(thd->server_status & SERVER_STATUS_AUTOCOMMIT);
flags.pkt_nr= net->pkt_nr;
flags.character_set_client_num=
@@ -1189,7 +1226,7 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu, div_precision: %lu, \
def_week_frmt: %lu, in_trans: %d, autocommit: %d",
(int)flags.client_long_flag,
(int)flags.client_protocol_41,
- (int)flags.result_in_binary_protocol,
+ (int)flags.protocol_type,
(int)flags.more_results_exists,
flags.pkt_nr,
flags.character_set_client_num,
@@ -1261,7 +1298,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
/* Check if another thread is processing the same query? */
Query_cache_block *competitor = (Query_cache_block *)
- hash_search(&queries, (uchar*) thd->query(), tot_length);
+ my_hash_search(&queries, (uchar*) thd->query(), tot_length);
DBUG_PRINT("qcache", ("competitor 0x%lx", (ulong) competitor));
if (competitor == 0)
{
@@ -1290,7 +1327,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
refused++;
DBUG_PRINT("warning", ("tables list including failed"));
- hash_delete(&queries, (uchar *) query_block);
+ my_hash_delete(&queries, (uchar *) query_block);
header->unlock_n_destroy();
free_memory_block(query_block);
unlock();
@@ -1299,8 +1336,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
double_linked_list_simple_include(query_block, &queries_blocks);
inserts++;
queries_in_cache++;
- net->query_cache_query= (uchar*) query_block;
- header->writer(net);
+ thd->query_cache_tls.first_query_block= query_block;
+ header->writer(&thd->query_cache_tls);
header->tables_type(tables_type);
unlock();
@@ -1387,14 +1424,18 @@ send_data_in_chunks(NET *net, const uchar *packet, ulong len)
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 0 Query was not cached.
+ @retval 1 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;
*/
@@ -1403,7 +1444,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
{
ulonglong engine_data;
Query_cache_query *query;
- Query_cache_block *first_result_block, *result_block;
+#ifndef EMBEDDED_LIBRARY
+ Query_cache_block *first_result_block;
+#endif
+ Query_cache_block *result_block;
Query_cache_block_table *block_table, *block_table_end;
ulong tot_length;
Query_cache_query_flags flags;
@@ -1416,8 +1460,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_mode ||
+ thd->variables.query_cache_type == 0 || query_cache_size == 0)
goto err;
if (!thd->lex->safe_to_cache_query)
@@ -1498,12 +1542,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
if (query_cache_size == 0)
goto err_unlock;
- /*
- Check that we haven't forgot to reset the query cache variables;
- make sure there are no attached query cache writer to this thread.
- */
- DBUG_ASSERT(thd->net.query_cache_query == 0);
-
Query_cache_block *query_block;
tot_length= query_length + 1 + sizeof(size_t) +
@@ -1527,10 +1565,10 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
flags.client_long_flag= test(thd->client_capabilities & CLIENT_LONG_FLAG);
flags.client_protocol_41= test(thd->client_capabilities &
CLIENT_PROTOCOL_41);
- flags.result_in_binary_protocol= (unsigned int)thd->protocol->type();
+ flags.protocol_type= (unsigned int) thd->protocol->type();
flags.more_results_exists= test(thd->server_status &
SERVER_MORE_RESULTS_EXISTS);
- flags.in_trans= test(thd->server_status & SERVER_STATUS_IN_TRANS);
+ flags.in_trans= thd->in_active_multi_stmt_transaction();
flags.autocommit= test(thd->server_status & SERVER_STATUS_AUTOCOMMIT);
flags.pkt_nr= thd->net.pkt_nr;
flags.character_set_client_num= thd->variables.character_set_client->number;
@@ -1554,7 +1592,7 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu, div_precision: %lu, \
def_week_frmt: %lu, in_trans: %d, autocommit: %d",
(int)flags.client_long_flag,
(int)flags.client_protocol_41,
- (int)flags.result_in_binary_protocol,
+ (int)flags.protocol_type,
(int)flags.more_results_exists,
flags.pkt_nr,
flags.character_set_client_num,
@@ -1571,8 +1609,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
(int)flags.autocommit));
memcpy((uchar *)(sql + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
(uchar*) &flags, QUERY_CACHE_FLAGS_SIZE);
- query_block = (Query_cache_block *) hash_search(&queries, (uchar*) sql,
- tot_length);
+ query_block = (Query_cache_block *) my_hash_search(&queries, (uchar*) sql,
+ tot_length);
/* Quick abort on unlocked data */
if (query_block == 0 ||
query_block->query()->result() == 0 ||
@@ -1587,7 +1625,10 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
BLOCK_LOCK_RD(query_block);
query = query_block->query();
- result_block= first_result_block= query->result();
+ result_block= query->result();
+#ifndef EMBEDDED_LIBRARY
+ first_result_block= result_block;
+#endif
if (result_block == 0 || result_block->type != Query_cache_block::RESULT)
{
@@ -1598,7 +1639,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
}
DBUG_PRINT("qcache", ("Query have result 0x%lx", (ulong) query));
- if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ if (thd->in_multi_stmt_transaction_mode() &&
(query->tables_type() & HA_CACHE_TBL_TRANSACT))
{
DBUG_PRINT("qcache",
@@ -1649,7 +1690,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
table_list.db = table->db();
table_list.alias= table_list.table_name= table->table();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_table_access(thd,SELECT_ACL,&table_list, 1, TRUE))
+ if (check_table_access(thd,SELECT_ACL,&table_list, FALSE, 1,TRUE))
{
DBUG_PRINT("qcache",
("probably no SELECT access to %s.%s => return to normal processing",
@@ -1689,6 +1730,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
}
else
thd->lex->safe_to_cache_query= 0; // Don't try to cache this
+ /* End the statement transaction potentially started by engine. */
+ trans_rollback_stmt(thd);
goto err_unlock; // Parse query
}
else
@@ -1730,15 +1773,24 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
thd->limit_found_rows = query->found_rows();
thd->status_var.last_query_cost= 0.0;
- if (!thd->main_da.is_set())
- thd->main_da.disable_status();
+ /*
+ End the statement transaction potentially started by an
+ engine callback. We ignore the return value for now,
+ since as long as EOF packet is part of the query cache
+ response, we can't handle it anyway.
+ */
+ (void) trans_commit_stmt(thd);
+ if (!thd->stmt_da->is_set())
+ thd->stmt_da->disable_status();
BLOCK_UNLOCK_RD(query_block);
+ MYSQL_QUERY_CACHE_HIT(thd->query(), (ulong) thd->limit_found_rows);
DBUG_RETURN(1); // Result sent to client
err_unlock:
unlock();
err:
+ MYSQL_QUERY_CACHE_MISS(thd->query());
DBUG_RETURN(0); // Query was not cached
}
@@ -1751,9 +1803,10 @@ 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));
+ using_transactions= using_transactions && thd->in_multi_stmt_transaction_mode();
for (; tables_used; tables_used= tables_used->next_local)
{
DBUG_ASSERT(!using_transactions || tables_used->table!=0);
@@ -1772,8 +1825,7 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
invalidate_table(thd, tables_used);
}
- DBUG_EXECUTE_IF("wait_after_query_cache_invalidate",
- debug_wait_for_kill("wait_after_query_cache_invalidate"););
+ DEBUG_SYNC(thd, "wait_after_query_cache_invalidate");
DBUG_VOID_RETURN;
}
@@ -1781,6 +1833,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)
{
@@ -1806,8 +1861,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)");
@@ -1828,9 +1886,10 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (table)");
-
- using_transactions= using_transactions &&
- (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+
+ using_transactions= using_transactions && thd->in_multi_stmt_transaction_mode();
if (using_transactions &&
(table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT))
thd->add_changed_table(table);
@@ -1845,9 +1904,10 @@ 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));
+ using_transactions= using_transactions && thd->in_multi_stmt_transaction_mode();
if (using_transactions) // used for innodb => has_transactions() is TRUE
thd->add_changed_table(key, key_length);
else
@@ -1863,9 +1923,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.
@@ -1950,8 +2013,10 @@ void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
void Query_cache::flush()
{
DBUG_ENTER("Query_cache::flush");
- DBUG_EXECUTE_IF("wait_in_query_cache_flush1",
- debug_wait_for_kill("wait_in_query_cache_flush1"););
+ if (is_disabled())
+ DBUG_VOID_RETURN;
+
+ QC_DEBUG_SYNC("wait_in_query_cache_flush1");
lock_and_suspend();
if (query_cache_size > 0)
@@ -1981,6 +2046,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.
@@ -2019,8 +2087,8 @@ void Query_cache::destroy()
free_cache();
unlock();
- pthread_cond_destroy(&COND_cache_status_changed);
- pthread_mutex_destroy(&structure_guard_mutex);
+ mysql_cond_destroy(&COND_cache_status_changed);
+ mysql_mutex_destroy(&structure_guard_mutex);
initialized = 0;
}
DBUG_VOID_RETURN;
@@ -2034,10 +2102,21 @@ void Query_cache::destroy()
void Query_cache::init()
{
DBUG_ENTER("Query_cache::init");
- pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST);
- pthread_cond_init(&COND_cache_status_changed, NULL);
+ mysql_mutex_init(key_structure_guard_mutex,
+ &structure_guard_mutex, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(key_COND_cache_status_changed,
+ &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;
}
@@ -2176,9 +2255,9 @@ ulong Query_cache::init_cache()
DUMP(this);
- VOID(hash_init(&queries, &my_charset_bin, def_query_hash_size, 0, 0,
- query_cache_query_get_key, 0, 0));
-#ifndef FN_NO_CASE_SENCE
+ (void) my_hash_init(&queries, &my_charset_bin, def_query_hash_size, 0, 0,
+ query_cache_query_get_key, 0, 0);
+#ifndef FN_NO_CASE_SENSE
/*
If lower_case_table_names!=0 then db and table names are already
converted to lower case and we can use binary collation for their
@@ -2187,8 +2266,8 @@ ulong Query_cache::init_cache()
lower_case_table_names == 0 then we should distinguish my_table
and MY_TABLE cases and so again can use binary collation.
*/
- VOID(hash_init(&tables, &my_charset_bin, def_table_hash_size, 0, 0,
- query_cache_table_get_key, 0, 0));
+ (void) my_hash_init(&tables, &my_charset_bin, def_table_hash_size, 0, 0,
+ query_cache_table_get_key, 0, 0);
#else
/*
On windows, OS/2, MacOS X with HFS+ or any other case insensitive
@@ -2198,10 +2277,11 @@ ulong Query_cache::init_cache()
file system) and so should use case insensitive collation for
comparison.
*/
- VOID(hash_init(&tables,
- lower_case_table_names ? &my_charset_bin :
- files_charset_info,
- def_table_hash_size, 0, 0,query_cache_table_get_key, 0, 0));
+ (void) my_hash_init(&tables,
+ lower_case_table_names ? &my_charset_bin :
+ files_charset_info,
+ def_table_hash_size, 0, 0,query_cache_table_get_key,
+ 0, 0);
#endif
queries_in_cache = 0;
@@ -2249,10 +2329,10 @@ void Query_cache::free_cache()
{
DBUG_ENTER("Query_cache::free_cache");
- my_free((uchar*) cache, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(cache);
make_disabled();
- hash_free(&queries);
- hash_free(&tables);
+ my_hash_free(&queries);
+ my_hash_free(&tables);
DBUG_VOID_RETURN;
}
@@ -2276,9 +2356,7 @@ void Query_cache::free_cache()
void Query_cache::flush_cache()
{
-
- DBUG_EXECUTE_IF("wait_in_query_cache_flush2",
- debug_wait_for_kill("wait_in_query_cache_flush2"););
+ QC_DEBUG_SYNC("wait_in_query_cache_flush2");
my_hash_reset(&queries);
while (queries_blocks != 0)
@@ -2364,7 +2442,7 @@ void Query_cache::free_query_internal(Query_cache_block *query_block)
if (query->writer() != 0)
{
/* Tell MySQL that this query should not be cached anymore */
- query->writer()->query_cache_query= 0;
+ query->writer()->first_query_block= NULL;
query->writer(0);
}
double_linked_list_exclude(query_block, &queries_blocks);
@@ -2427,7 +2505,7 @@ void Query_cache::free_query(Query_cache_block *query_block)
(ulong) query_block,
query_block->query()->length() ));
- hash_delete(&queries,(uchar *) query_block);
+ my_hash_delete(&queries,(uchar *) query_block);
free_query_internal(query_block);
DBUG_VOID_RETURN;
@@ -2724,8 +2802,7 @@ void Query_cache::invalidate_table(THD *thd, TABLE *table)
void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length)
{
- DBUG_EXECUTE_IF("wait_in_query_cache_invalidate1",
- debug_wait_for_kill("wait_in_query_cache_invalidate1"); );
+ DEBUG_SYNC(thd, "wait_in_query_cache_invalidate1");
/*
Lock the query cache and queue all invalidation attempts to avoid
@@ -2733,9 +2810,7 @@ void Query_cache::invalidate_table(THD *thd, uchar * key, uint32 key_length)
*/
lock();
- DBUG_EXECUTE_IF("wait_in_query_cache_invalidate2",
- debug_wait_for_kill("wait_in_query_cache_invalidate2"); );
-
+ DEBUG_SYNC(thd, "wait_in_query_cache_invalidate2");
if (query_cache_size > 0)
invalidate_table_internal(thd, key, key_length);
@@ -2756,7 +2831,7 @@ void
Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length)
{
Query_cache_block *table_block=
- (Query_cache_block*)hash_search(&tables, key, key_length);
+ (Query_cache_block*)my_hash_search(&tables, key, key_length);
if (table_block)
{
Query_cache_block_table *list_root= table_block->table(0);
@@ -2785,7 +2860,6 @@ Query_cache::invalidate_query_block_list(THD *thd,
Query_cache_block *query_block= list_root->next->block();
BLOCK_LOCK_WR(query_block);
free_query(query_block);
- DBUG_EXECUTE_IF("debug_cache_locks", sleep(10););
}
}
@@ -2954,7 +3028,7 @@ Query_cache::insert_table(uint key_len, char *key,
THD *thd= current_thd;
Query_cache_block *table_block=
- (Query_cache_block *)hash_search(&tables, (uchar*) key, key_len);
+ (Query_cache_block *) my_hash_search(&tables, (uchar*) key, key_len);
if (table_block &&
table_block->table()->engine_data() != engine_data)
@@ -3070,7 +3144,7 @@ void Query_cache::unlink_table(Query_cache_block_table *node)
Query_cache_block *table_block= neighbour->block();
double_linked_list_exclude(table_block,
&tables_blocks);
- hash_delete(&tables,(uchar *) table_block);
+ my_hash_delete(&tables,(uchar *) table_block);
free_memory_block(table_block);
}
DBUG_VOID_RETURN;
@@ -3577,7 +3651,8 @@ Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
*/
TABLE_COUNTER_TYPE
-Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
+Query_cache::is_cacheable(THD *thd, size_t query_len, const char *query,
+ LEX *lex,
TABLE_LIST *tables_used, uint8 *tables_type)
{
TABLE_COUNTER_TYPE table_count;
@@ -3597,7 +3672,7 @@ Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
tables_type)))
DBUG_RETURN(0);
- if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
+ if (thd->in_multi_stmt_transaction_mode() &&
((*tables_type)&HA_CACHE_TBL_TRANSACT))
{
DBUG_PRINT("qcache", ("not in autocommin mode"));
@@ -3754,7 +3829,7 @@ my_bool Query_cache::move_by_type(uchar **border,
uchar *key;
size_t key_length;
key=query_cache_table_get_key((uchar*) block, &key_length, 0);
- hash_first(&tables, (uchar*) key, key_length, &record_idx);
+ my_hash_first(&tables, (uchar*) key, key_length, &record_idx);
block->destroy();
new_block->init(len);
@@ -3788,7 +3863,7 @@ my_bool Query_cache::move_by_type(uchar **border,
/* Fix pointer to table name */
new_block->table()->table(new_block->table()->db() + tablename_offset);
/* Fix hash to point at moved block */
- hash_replace(&tables, &record_idx, (uchar*) new_block);
+ my_hash_replace(&tables, &record_idx, (uchar*) new_block);
DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
len, (ulong) new_block, (ulong) *border));
@@ -3814,7 +3889,7 @@ my_bool Query_cache::move_by_type(uchar **border,
uchar *key;
size_t key_length;
key=query_cache_query_get_key((uchar*) block, &key_length, 0);
- hash_first(&queries, (uchar*) key, key_length, &record_idx);
+ my_hash_first(&queries, (uchar*) key, key_length, &record_idx);
// Move table of used tables
memmove((char*) new_block->table(0), (char*) block->table(0),
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
@@ -3870,19 +3945,19 @@ my_bool Query_cache::move_by_type(uchar **border,
} while ( result_block != first_result_block );
}
Query_cache_query *new_query= ((Query_cache_query *) new_block->data());
- my_rwlock_init(&new_query->lock, NULL);
+ mysql_rwlock_init(key_rwlock_query_cache_query_lock, &new_query->lock);
/*
If someone is writing to this block, inform the writer that the block
has been moved.
*/
- NET *net = new_block->query()->writer();
- if (net != 0)
+ Query_cache_tls *query_cache_tls= new_block->query()->writer();
+ if (query_cache_tls != NULL)
{
- net->query_cache_query= (uchar*) new_block;
+ query_cache_tls->first_query_block= new_block;
}
/* Fix hash to point at moved block */
- hash_replace(&queries, &record_idx, (uchar*) new_block);
+ my_hash_replace(&queries, &record_idx, (uchar*) new_block);
DBUG_PRINT("qcache", ("moved %lu bytes to 0x%lx, new gap at 0x%lx",
len, (ulong) new_block, (ulong) *border));
break;
@@ -4293,13 +4368,13 @@ my_bool Query_cache::check_integrity(bool locked)
if (!locked)
lock_and_suspend();
- if (hash_check(&queries))
+ if (my_hash_check(&queries))
{
DBUG_PRINT("error", ("queries hash is damaged"));
result = 1;
}
- if (hash_check(&tables))
+ if (my_hash_check(&tables))
{
DBUG_PRINT("error", ("tables hash is damaged"));
result = 1;
@@ -4466,7 +4541,7 @@ my_bool Query_cache::check_integrity(bool locked)
(ulong) block, (uint) block->type));
size_t length;
uchar *key = query_cache_query_get_key((uchar*) block, &length, 0);
- uchar* val = hash_search(&queries, key, length);
+ uchar* val = my_hash_search(&queries, key, length);
if (((uchar*)block) != val)
{
DBUG_PRINT("error", ("block 0x%lx found in queries hash like 0x%lx",
@@ -4501,7 +4576,7 @@ my_bool Query_cache::check_integrity(bool locked)
(ulong) block, (uint) block->type));
size_t length;
uchar *key = query_cache_table_get_key((uchar*) block, &length, 0);
- uchar* val = hash_search(&tables, key, length);
+ uchar* val = my_hash_search(&tables, key, length);
if (((uchar*)block) != val)
{
DBUG_PRINT("error", ("block 0x%lx found in tables hash like 0x%lx",
@@ -4741,3 +4816,4 @@ err2:
#endif /* DBUG_OFF */
#endif /*HAVE_QUERY_CACHE*/
+