Commit f5f896b4 authored by unknown's avatar unknown
Browse files

support of concurent query cache resizing (BUG#12848)


sql/mysql_priv.h:
  initialisation moved to mysqld.cc
sql/mysqld.cc:
  initialisation moved to mysqld.cc
sql/sql_cache.cc:
  support of concurent query cache resizing:
        - resizing made atomic
        - check stack size after each quard mutex lock
sql/sql_cache.h:
  initialisation moved to mysqld.cc
  removed uneed parameter (now it is always under guard mutex protection or called from destruction)
parent 472b002b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -318,6 +318,7 @@ inline THD *_current_thd(void)
#define query_cache_store_query(A, B) query_cache.store_query(A, B)
#define query_cache_destroy() query_cache.destroy()
#define query_cache_result_size_limit(A) query_cache.result_size_limit(A)
#define query_cache_init() query_cache.init()
#define query_cache_resize(A) query_cache.resize(A)
#define query_cache_invalidate3(A, B, C) query_cache.invalidate(A, B, C)
#define query_cache_invalidate1(A) query_cache.invalidate(A)
@@ -329,6 +330,7 @@ inline THD *_current_thd(void)
#define query_cache_store_query(A, B)
#define query_cache_destroy()
#define query_cache_result_size_limit(A)
#define query_cache_init()
#define query_cache_resize(A)
#define query_cache_invalidate3(A, B, C)
#define query_cache_invalidate1(A)
+1 −0
Original line number Diff line number Diff line
@@ -2461,6 +2461,7 @@ You should consider changing lower_case_table_names to 1 or 2",
    unireg_abort(1);
  }
  query_cache_result_size_limit(query_cache_limit);
  query_cache_init();
  query_cache_resize(query_cache_size);
  randominit(&sql_rand,(ulong) start_time,(ulong) start_time/2);
  reset_floating_point_exceptions();
+80 −34
Original line number Diff line number Diff line
@@ -563,13 +563,18 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
{
  DBUG_ENTER("query_cache_insert");

#ifndef DBUG_OFF
  // Check if we have called query_cache.wreck() (which disables the cache)
  if (query_cache.query_cache_size == 0)
  STRUCT_LOCK(&query_cache.structure_guard_mutex);
  /*
    It is very unlikely that following condition is TRUE (it is possible
    only if other thread is resizing cache), so we check it only after guard
    mutex lock
  */
  if (unlikely(query_cache.query_cache_size == 0))
  {
    STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
    DBUG_VOID_RETURN;
#endif
  }

  STRUCT_LOCK(&query_cache.structure_guard_mutex);
  Query_cache_block *query_block = ((Query_cache_block*)
				    net->query_cache_query);
  if (query_block)
@@ -612,14 +617,20 @@ void query_cache_abort(NET *net)
{
  DBUG_ENTER("query_cache_abort");

#ifndef DBUG_OFF
  // Check if we have called query_cache.wreck() (which disables the cache)
  if (query_cache.query_cache_size == 0)
    DBUG_VOID_RETURN;
#endif
  if (net->query_cache_query != 0)	// Quick check on unlocked structure
  {
    STRUCT_LOCK(&query_cache.structure_guard_mutex);
    /*
      It is very unlikely that following condition is TRUE (it is possible
      only if other thread is resizing cache), so we check it only after guard
      mutex lock
    */
    if (unlikely(query_cache.query_cache_size == 0))
    {
      STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
      DBUG_VOID_RETURN;
    }

    Query_cache_block *query_block = ((Query_cache_block*)
				       net->query_cache_query);
    if (query_block)			// Test if changed by other thread
@@ -641,14 +652,20 @@ void query_cache_end_of_result(NET *net)
{
  DBUG_ENTER("query_cache_end_of_result");

#ifndef DBUG_OFF
  // Check if we have called query_cache.wreck() (which disables the cache)
  if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
#endif

  if (net->query_cache_query != 0)	// Quick check on unlocked structure
  {
    STRUCT_LOCK(&query_cache.structure_guard_mutex);
    /*
      It is very unlikely that following condition is TRUE (it is possible
      only if other thread is resizing cache), so we check it only after guard
      mutex lock
    */
    if (unlikely(query_cache.query_cache_size == 0))
    {
      STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
      DBUG_VOID_RETURN;
    }

    Query_cache_block *query_block = ((Query_cache_block*)
				      net->query_cache_query);
    if (query_block)
@@ -728,9 +745,14 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
  DBUG_ENTER("Query_cache::resize");
  DBUG_PRINT("qcache", ("from %lu to %lu",query_cache_size,
			query_cache_size_arg));
  free_cache(0);
  DBUG_ASSERT(initialized);
  STRUCT_LOCK(&structure_guard_mutex);
  if (query_cache_size > 0)
    free_cache();
  query_cache_size= query_cache_size_arg;
  DBUG_RETURN(::query_cache_size= init_cache());
  ::query_cache_size= init_cache();
  STRUCT_UNLOCK(&structure_guard_mutex);
  DBUG_RETURN(::query_cache_size);
}


@@ -1307,7 +1329,7 @@ void Query_cache::destroy()
  }
  else
  {
    free_cache(1);
    free_cache();
    pthread_mutex_destroy(&structure_guard_mutex);
    initialized = 0;
  }
@@ -1336,8 +1358,6 @@ ulong Query_cache::init_cache()
  int align;

  DBUG_ENTER("Query_cache::init_cache");
  if (!initialized)
    init();
  approx_additional_data_size = (sizeof(Query_cache) +
				 sizeof(gptr)*(def_query_hash_size+
					       def_table_hash_size));
@@ -1395,14 +1415,9 @@ ulong Query_cache::init_cache()
    goto err;
  query_cache_size -= additional_data_size;

  STRUCT_LOCK(&structure_guard_mutex);

  if (!(cache= (byte *)
        my_malloc_lock(query_cache_size+additional_data_size, MYF(0))))
  {
    STRUCT_UNLOCK(&structure_guard_mutex);
    goto err;
  }

  DBUG_PRINT("qcache", ("cache length %lu, min unit %lu, %u bins",
		      query_cache_size, min_allocation_unit, mem_bin_num));
@@ -1482,7 +1497,6 @@ ulong Query_cache::init_cache()

  queries_in_cache = 0;
  queries_blocks = 0;
  STRUCT_UNLOCK(&structure_guard_mutex);
  DBUG_RETURN(query_cache_size +
	      additional_data_size + approx_additional_data_size);

@@ -1498,6 +1512,7 @@ void Query_cache::make_disabled()
{
  DBUG_ENTER("Query_cache::make_disabled");
  query_cache_size= 0;
  queries_blocks= 0;
  free_memory= 0;
  bins= 0;
  steps= 0;
@@ -1509,14 +1524,11 @@ void Query_cache::make_disabled()
}


void Query_cache::free_cache(my_bool destruction)
void Query_cache::free_cache()
{
  DBUG_ENTER("Query_cache::free_cache");
  if (query_cache_size > 0)
  {
    if (!destruction)
      STRUCT_LOCK(&structure_guard_mutex);

    flush_cache();
#ifndef DBUG_OFF
    if (bins[0].free_blocks == 0)
@@ -1538,8 +1550,6 @@ void Query_cache::free_cache(my_bool destruction)
    make_disabled();
    hash_free(&queries);
    hash_free(&tables);
    if (!destruction)
      STRUCT_UNLOCK(&structure_guard_mutex);
  }
  DBUG_VOID_RETURN;
}
@@ -2149,7 +2159,19 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min,
  }

  if (!under_guard)
  {
    STRUCT_LOCK(&structure_guard_mutex);
    /*
      It is very unlikely that following condition is TRUE (it is possible
      only if other thread is resizing cache), so we check it only after
      guard mutex lock
    */
    if (unlikely(query_cache.query_cache_size == 0))
    {
      STRUCT_UNLOCK(&structure_guard_mutex);
      DBUG_RETURN(0);
    }
  }

  /* Free old queries until we have enough memory to store this block */
  Query_cache_block *block;
@@ -2606,6 +2628,17 @@ void Query_cache::pack_cache()
{
  DBUG_ENTER("Query_cache::pack_cache");
  STRUCT_LOCK(&structure_guard_mutex);
  /*
    It is very unlikely that following condition is TRUE (it is possible
    only if other thread is resizing cache), so we check it only after
    guard mutex lock
  */
  if (unlikely(query_cache_size == 0))
  {
    STRUCT_UNLOCK(&structure_guard_mutex);
    DBUG_VOID_RETURN;
  }

  DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););

  byte *border = 0;
@@ -2915,6 +2948,7 @@ my_bool Query_cache::join_results(ulong join_limit)
  STRUCT_LOCK(&structure_guard_mutex);
  if (queries_blocks != 0)
  {
    DBUG_ASSERT(query_cache_size > 0);
    Query_cache_block *block = queries_blocks;
    do
    {
@@ -3209,7 +3243,19 @@ my_bool Query_cache::check_integrity(bool not_locked)
    DBUG_RETURN(0);
  }
  if (!not_locked)
  {
    STRUCT_LOCK(&structure_guard_mutex);
    /*
      It is very unlikely that following condition is TRUE (it is possible
      only if other thread is resizing cache), so we check it only after
      guard mutex lock
    */
    if (unlikely(query_cache_size == 0))
    {
      STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
      DBUG_RETURN(0);
    }
  }

  if (hash_check(&queries))
  {
+3 −2
Original line number Diff line number Diff line
@@ -310,10 +310,9 @@ class Query_cache
    Following function control structure_guard_mutex
    by themself or don't need structure_guard_mutex
  */
  void init();
  ulong init_cache();
  void make_disabled();
  void free_cache(my_bool destruction);
  void free_cache();
  Query_cache_block *write_block_data(ulong data_len, gptr data,
				       ulong header_len,
				       Query_cache_block::block_type type,
@@ -346,6 +345,8 @@ class Query_cache
	      uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
	      uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);

  /* initialize cache (mutex) */
  void init();
  /* resize query cache (return real query size, 0 if disabled) */
  ulong resize(ulong query_cache_size);
  inline void result_size_limit(ulong limit){query_cache_limit=limit;}