Bug#56822: Add a thread state for sessions waiting on the query cache lock

Only wait for a single debug signal at a time as the signal state
is global. Also, do not activate the query cache debug sync points
if the thread has no associated THD session.
This commit is contained in:
Davi Arnaut 2010-10-08 09:16:20 -03:00
parent 921fd52975
commit 657b157511
3 changed files with 39 additions and 13 deletions

View File

@ -123,16 +123,20 @@ SET DEBUG_SYNC="now WAIT_FOR parked1_1";
** On THD2: Insert a result into the cache. This attempt will be blocked ** On THD2: Insert a result into the cache. This attempt will be blocked
** because of a debug hook placed just before the mutex lock after which ** because of a debug hook placed just before the mutex lock after which
** the first part of the result set is written. ** the first part of the result set is written.
SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1";
SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3; SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3;
=================================== Connection default
** Assert that the SELECT-stmt thread reaches the sync point.
SET DEBUG_SYNC="now WAIT_FOR parked2";
**
**
=================================== Connection thd3 =================================== Connection thd3
** On THD3: Insert another result into the cache and block on the same ** On THD3: Insert another result into the cache and block on the same
** debug hook. ** debug hook.
SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1";
SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;; SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5;
=================================== Connection default =================================== Connection default
** Assert that the two SELECT-stmt threads to reach the hook. ** Assert that the SELECT-stmt thread reaches the sync point.
SET DEBUG_SYNC="now WAIT_FOR parked2";
SET DEBUG_SYNC="now WAIT_FOR parked3"; SET DEBUG_SYNC="now WAIT_FOR parked3";
** **
** **

View File

@ -170,20 +170,26 @@ connection thd2;
--echo ** On THD2: Insert a result into the cache. This attempt will be blocked --echo ** On THD2: Insert a result into the cache. This attempt will be blocked
--echo ** because of a debug hook placed just before the mutex lock after which --echo ** because of a debug hook placed just before the mutex lock after which
--echo ** the first part of the result set is written. --echo ** the first part of the result set is written.
SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2"; SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked2 WAIT_FOR go2 EXECUTE 1";
--send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3 --send SELECT SQL_CACHE * FROM t2 UNION SELECT * FROM t3
connection default;
--echo =================================== Connection default
--echo ** Assert that the SELECT-stmt thread reaches the sync point.
SET DEBUG_SYNC="now WAIT_FOR parked2";
--echo **
--echo **
connection thd3; connection thd3;
--echo =================================== Connection thd3 --echo =================================== Connection thd3
--echo ** On THD3: Insert another result into the cache and block on the same --echo ** On THD3: Insert another result into the cache and block on the same
--echo ** debug hook. --echo ** debug hook.
SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3"; SET DEBUG_SYNC="wait_in_query_cache_insert SIGNAL parked3 WAIT_FOR go3 EXECUTE 1";
--send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5; --send SELECT SQL_CACHE * FROM t4 UNION SELECT * FROM t5
connection default; connection default;
--echo =================================== Connection default --echo =================================== Connection default
--echo ** Assert that the two SELECT-stmt threads to reach the hook. --echo ** Assert that the SELECT-stmt thread reaches the sync point.
SET DEBUG_SYNC="now WAIT_FOR parked2";
SET DEBUG_SYNC="now WAIT_FOR parked3"; SET DEBUG_SYNC="now WAIT_FOR parked3";
--echo ** --echo **
--echo ** --echo **

View File

@ -384,6 +384,22 @@ TODO list:
#endif #endif
/**
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. 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. Sets the thread state name in the constructor, resets on destructor.
@ -879,7 +895,7 @@ Query_cache::insert(Query_cache_tls *query_cache_tls,
if (is_disabled() || query_cache_tls->first_query_block == NULL) if (is_disabled() || query_cache_tls->first_query_block == NULL)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
DEBUG_SYNC(current_thd, "wait_in_query_cache_insert"); QC_DEBUG_SYNC("wait_in_query_cache_insert");
if (try_lock()) if (try_lock())
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -1975,7 +1991,7 @@ void Query_cache::flush()
if (is_disabled()) if (is_disabled())
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
DEBUG_SYNC(current_thd, "wait_in_query_cache_flush1"); QC_DEBUG_SYNC("wait_in_query_cache_flush1");
lock_and_suspend(); lock_and_suspend();
if (query_cache_size > 0) if (query_cache_size > 0)
@ -2315,7 +2331,7 @@ void Query_cache::free_cache()
void Query_cache::flush_cache() void Query_cache::flush_cache()
{ {
DEBUG_SYNC(current_thd, "wait_in_query_cache_flush2"); QC_DEBUG_SYNC("wait_in_query_cache_flush2");
my_hash_reset(&queries); my_hash_reset(&queries);
while (queries_blocks != 0) while (queries_blocks != 0)