Commit d7e2ef88 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua
Browse files

Merge abelkin@work.mysql.com:/home/bk/mysql-4.0

into sanja.is.com.ua:/home/bell/mysql/mysql-4
parents e95ac89a 11920dbb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -179,8 +179,6 @@ create table t2 (a text not null);
create table t21 (a text not null);
create table t3 (a text not null);
insert into t1 values("1111111111111111111111111111111111111111111111111111");
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t2 select * from t1;
insert into t1 select * from t2;
insert into t2 select * from t1;
@@ -196,6 +194,8 @@ insert into t1 select * from t2;
insert into t2 select * from t1;
insert into t1 select * from t2;
insert into t2 select * from t1;
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t1 select * from t2;
insert into t2 select * from t1;
insert into t1 select * from t2;
+3 −2
Original line number Diff line number Diff line
@@ -93,8 +93,6 @@ create table t2 (a text not null);
create table t21 (a text not null);
create table t3 (a text not null);
insert into t1 values("1111111111111111111111111111111111111111111111111111");
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t2 select * from t1;
insert into t1 select * from t2;
insert into t2 select * from t1;
@@ -110,6 +108,9 @@ insert into t1 select * from t2;
insert into t2 select * from t1;
insert into t1 select * from t2;
insert into t2 select * from t1;
# t11 and t21 must be over 4Kb (QUERY_CACHE_MIN_RESULT_DATA_SIZE)
insert into t11 select * from t1;
insert into t21 select * from t1;
insert into t1 select * from t2;
insert into t2 select * from t1;
insert into t1 select * from t2;
+39 −13
Original line number Diff line number Diff line
@@ -273,9 +273,6 @@ TODO list:

  - Invalidate queries that use innoDB tables changed in transaction & remove
      invalidation by table type
  - Allocate bigger blocks for results (may be we should estimate the 
        allocatedblock's size dynamicaly) and shrink last block with 
        results in query_cache_end_of_result.
  - Delayed till after-parsing qache answer (for column rights processing)
  - Optimize cache resizing
      - if new_size < old_size then pack & shrink
@@ -657,9 +654,14 @@ void query_cache_end_of_result(NET *net)
    {
      DUMP(&query_cache);
      BLOCK_LOCK_WR(query_block);
      Query_cache_query *header = query_block->query();
      Query_cache_block *last_result_block = header->result()->prev;
      ulong allign_size = ALIGN_SIZE(last_result_block->used);
      ulong len = max(query_cache.min_allocation_unit, allign_size);
      if (last_result_block->length >= query_cache.min_allocation_unit + len)
	query_cache.split_block(last_result_block,len);
      STRUCT_UNLOCK(&query_cache.structure_guard_mutex);

      Query_cache_query *header = query_block->query();
#ifndef DBUG_OFF
      if (header->result() == 0)
      {
@@ -1585,10 +1587,11 @@ Query_cache::append_result_data(Query_cache_block **current_block,
  */

  // Try join blocks if physically next block is free...
  ulong tail = data_len - last_block_free_space;
  ulong append_min = get_min_append_result_data_size();
  if (last_block_free_space < data_len &&
      append_next_free_block(last_block,
			     max(data_len - last_block_free_space,
				 QUERY_CACHE_MIN_RESULT_DATA_SIZE)))
			     max(tail, append_min)))
    last_block_free_space = last_block->length - last_block->used;
  // If no space in last block (even after join) allocate new block
  if (last_block_free_space < data_len)
@@ -1648,7 +1651,8 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
    structure_guard_mutex and copy data.
  */

  my_bool success = allocate_data_chain(result_block, data_len, query_block);
  my_bool success = allocate_data_chain(result_block, data_len, query_block,
					type == Query_cache_block::RES_BEG);
  if (success)
  {
    // It is success (nobody can prevent us write data)
@@ -1693,13 +1697,28 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
  DBUG_RETURN(success);
}

inline ulong Query_cache::get_min_first_result_data_size()
{
  if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
    return min_result_data_size;
  ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
  avg_result = min(avg_result, query_cache_limit);
  return max(min_result_data_size, avg_result);
}

inline ulong Query_cache::get_min_append_result_data_size()
{
  return min_result_data_size;
}

/*
  Allocate one or more blocks to hold data
*/

my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
					 ulong data_len,
					 Query_cache_block *query_block)
					 Query_cache_block *query_block,
					 my_bool first_block)
{
  ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
			   ALIGN_SIZE(sizeof(Query_cache_result)));
@@ -1708,7 +1727,10 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
  DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
		      data_len, all_headers_len));

  *result_block = allocate_block(max(min_result_data_size,len),
  ulong min_size = (first_block ?
		    get_min_first_result_data_size():
		    get_min_append_result_data_size());
  *result_block = allocate_block(max(min_size,len),
				 min_result_data_size == 0,
				 all_headers_len + min_result_data_size,
				 1);
@@ -1732,7 +1754,7 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
      Query_cache_block *next_block;
      if ((success = allocate_data_chain(&next_block,
					 len - new_block->length,
					 query_block)))
					 query_block, first_block)))
	double_linked_list_join(new_block, next_block);
    }
    if (success)
@@ -1964,7 +1986,7 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min,

  if (block != 0)				// If we found a suitable block
  {
    if (block->length > ALIGN_SIZE(len) + min_allocation_unit)
    if (block->length >= ALIGN_SIZE(len) + min_allocation_unit)
      split_block(block,ALIGN_SIZE(len));
  }

@@ -2082,7 +2104,11 @@ void Query_cache::split_block(Query_cache_block *block,ulong len)
  new_block->pprev = block;
  new_block->pnext->pprev = new_block;

  if (block->type == Query_cache_block::FREE)
    // if block was free then it already joined with all free neighbours
    insert_into_free_memory_list(new_block);
  else
    free_memory_block(new_block);

  DBUG_PRINT("qcache", ("split 0x%lx (%lu) new 0x%lx",
		      (ulong) block, len, (ulong) new_block));
+15 −5
Original line number Diff line number Diff line
@@ -25,14 +25,22 @@
   if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then
   QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly
*/
#define QUERY_CACHE_MIN_ALLOCATION_UNIT		0
#define QUERY_CACHE_MIN_ALLOCATION_UNIT		512

/* inittial size of hashes */
#define QUERY_CACHE_DEF_QUERY_HASH_SIZE		1024
#define QUERY_CACHE_DEF_TABLE_HASH_SIZE		1024

/* minimal result data size when data allocated */
#define QUERY_CACHE_MIN_RESULT_DATA_SIZE	1024
#define QUERY_CACHE_MIN_RESULT_DATA_SIZE	1024*4

/* 
   start estimation of first result block size only when number of queries
   bigger then: 
*/
#define QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER 3



/* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */
#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2	4
@@ -234,8 +242,7 @@ class Query_cache
    query structure we locked an internal query block mutex.
    LOCK SEQUENCE (to prevent deadlocks):
      1. structure_guard_mutex
      2. query block / table block / free block
      3. results blocks (only when must become free).
      2. query block (for operation inside query (query block/results))
  */
  pthread_mutex_t structure_guard_mutex;
  byte *cache;					// cache memory
@@ -271,7 +278,8 @@ class Query_cache
  void free_query(Query_cache_block *point);
  my_bool allocate_data_chain(Query_cache_block **result_block,
			      ulong data_len,
			      Query_cache_block *query_block);
			      Query_cache_block *query_block,
			      my_bool first_block);
  void invalidate_table(TABLE_LIST *table);
  void invalidate_table(TABLE *table);
  void invalidate_table(Query_cache_block *table_block);
@@ -328,6 +336,8 @@ class Query_cache
			    Query_cache_block *parent,
			    Query_cache_block::block_type
			    type=Query_cache_block::RESULT);
  inline ulong get_min_first_result_data_size();
  inline ulong get_min_append_result_data_size();
  Query_cache_block *allocate_block(ulong len, my_bool not_less,
				     ulong min,
				     my_bool under_guard=0);