1
0
mirror of https://github.com/MariaDB/server.git synced 2025-11-24 06:01:25 +03:00
Files
mariadb/sql/sql_cache.h
Kristofer Pettersson 02e5ad9881 Bug#43758 Query cache can lock up threads in 'freeing items' state
Early patch submitted for discussion.

It is possible for more than one thread to enter the condition
in query_cache_insert(), but the condition predicate is to
signal one thread each time the cache status changes between
the following states: {NO_FLUSH_IN_PROGRESS,FLUSH_IN_PROGRESS,
TABLE_FLUSH_IN_PROGRESS}

Consider three threads THD1, THD2, THD3

   THD2: select ... => Got a writer in ::store_query
   THD3: select ... => Got a writer in ::store_query
   THD1: flush tables => qc status= FLUSH_IN_PROGRESS;
                      new writers are blocked.
   THD2: select ... => Still got a writer and enters cond in
                       query_cache_insert
   THD3: select ... => Still got a writer and enters cond in
                       query_cache_insert
   THD1: flush tables => finished and signal status change.
   THD2: select ... => Wakes up and completes the insert.
   THD3: select ... => Happily waiting for better times. Why hurry?

This patch is a refactoring of this lock system. It introduces four new methods:
   Query_cache::try_lock()
   Query_cache::lock()
   Query_cache::lock_and_suspend()
   Query_cache::unlock()

This change also deprecates wait_while_table_flush_is_in_progress(). All threads are
queued and put on a conditional wait. On each unlock the queue is signalled. This resolve
the issues with left over threads. To assure that no threads are spending unnecessary
time waiting a signal broadcast is issued every time a lock is taken before a full
cache flush.

mysql-test/r/query_cache_debug.result:
  * Added test case for bug43758
mysql-test/t/query_cache_debug.test:
  * Added test case for bug43758
sql/sql_cache.cc:
  * Replaced calls to wait_while_table_flush_is_in_progress() with
    calls to try_lock(), lock_and_suspend() and unlock().
  * Renamed enumeration Cache_status to Cache_lock_status.
  * Renamed enumeration items to UNLOCKED, LOCKED_NO_WAIT and LOCKED.
    If the LOCKED_NO_WAIT lock type is used to lock the query cache, other
    threads using try_lock() will fail to acquire the lock.
    This is useful if the query cache is temporary disabled due to 
    a full table flush.
sql/sql_cache.h:
  * Replaced calls to wait_while_table_flush_is_in_progress() with
    calls to try_lock(), lock_and_suspend() and unlock().
  * Renamed enumeration Cache_status to Cache_lock_status.
  * Renamed enumeration items to UNLOCKED, LOCKED_NO_WAIT and LOCKED.
    If the LOCKED_NO_WAIT lock type is used to lock the query cache, other
    threads using try_lock() will fail to acquire the lock.
    This is useful if the query cache is temporary disabled due to 
    a full table flush.
2009-06-16 10:34:47 +02:00

17 KiB