• Kristofer Pettersson's avatar
    Bug#43758 Query cache can lock up threads in 'freeing items' state · b22d02ad
    Kristofer Pettersson authored
    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.
    b22d02ad
sql_cache.cc 141 KB