Loading mysql-test/r/query_cache.result +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading mysql-test/t/query_cache.test +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading sql/sql_cache.cc +39 −13 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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))); Loading @@ -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); Loading @@ -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) Loading Loading @@ -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)); } Loading Loading @@ -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)); Loading sql/sql_cache.h +15 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading
mysql-test/r/query_cache.result +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
mysql-test/t/query_cache.test +3 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading
sql/sql_cache.cc +39 −13 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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) Loading Loading @@ -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))); Loading @@ -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); Loading @@ -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) Loading Loading @@ -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)); } Loading Loading @@ -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)); Loading
sql/sql_cache.h +15 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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); Loading Loading @@ -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); Loading