MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:kroki Date:January 22 2007 10:03am
Subject:bk commit into 5.0 tree (kroki:1.2320) BUG#23527
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tomash. When tomash does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-01-22 13:03:38+03:00, kroki@stripped +1 -0
  BUG#23527: set global query_cache_size can crash the server under
             high load
  
  MySQL server could crash if two or more threads would initiate query
  cache resize at the moments very close in time.
  
  The problem was introduced with the fix of bug 21051 in 5.0 and 5.1:
  simultaneous query cache resizes would wait for the first one in
  progress, but then each thread would try to finish the operation,
  accessing the data that was already reset (attempt to dereference
  'bins' pointer, which may be NULL already).
  
  The solution is to check after synchronization if another thread has
  done the reset already (test 'query_cache_size > 0' again).
  
  No test case is provided because the bug is a subject to a race.

  sql/sql_cache.cc@stripped, 2007-01-22 13:03:34+03:00, kroki@stripped +11 -1
    We release 'structure_guard_mutex' in flush_cache(), so after the
    call we check if another thread had reset the cache before us.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	kroki
# Host:	moonlight.home
# Root:	/home/tomash/src/mysql_ab/mysql-5.0-bug23527

--- 1.95/sql/sql_cache.cc	2007-01-22 13:03:45 +03:00
+++ 1.96/sql/sql_cache.cc	2007-01-22 13:03:45 +03:00
@@ -1766,8 +1766,18 @@ void Query_cache::free_cache()
 {
   DBUG_ENTER("Query_cache::free_cache");
   if (query_cache_size > 0)
-  {
     flush_cache();
+  /*
+    There may be two free_cache() calls in progress, because we
+    release 'structure_guard_mutex' in flush_cache().  When the second
+    flush_cache() wakes up from the wait on 'COND_flush_finished', the
+    first call to free_cache() has done its job.  So we have to test
+    'query_cache_size > 0' the second time to see if the cache wasn't
+    reset by other thread, or if it was reset and was re-enabled then.
+    If the cache was reset, then we have nothing to do here.
+  */
+  if (query_cache_size > 0)
+  {
 #ifndef DBUG_OFF
     if (bins[0].free_blocks == 0)
     {
Thread
bk commit into 5.0 tree (kroki:1.2320) BUG#23527kroki22 Jan