Commit d39dc6a9 authored by hf@deer.(none)'s avatar hf@deer.(none)

Fix for bug #5730 (Query cache crashes mysql)

here i deleted the recursion from the querycache's memory allocation
parent e79dfd91
...@@ -1953,55 +1953,55 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block, ...@@ -1953,55 +1953,55 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
{ {
ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) + ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result))); ALIGN_SIZE(sizeof(Query_cache_result)));
ulong len= data_len + all_headers_len; ulong min_size = (first_block_arg ?
ulong align_len= ALIGN_SIZE(len); get_min_first_result_data_size():
get_min_append_result_data_size());
Query_cache_block *prev_block= NULL;
Query_cache_block *new_block;
DBUG_ENTER("Query_cache::allocate_data_chain"); DBUG_ENTER("Query_cache::allocate_data_chain");
DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu", DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
data_len, all_headers_len)); data_len, all_headers_len));
ulong min_size = (first_block_arg ? do
get_min_first_result_data_size(): {
get_min_append_result_data_size()); ulong len= data_len + all_headers_len;
*result_block = allocate_block(max(min_size, align_len), ulong align_len= ALIGN_SIZE(len);
if (!(new_block= allocate_block(max(min_size, align_len),
min_result_data_size == 0, min_result_data_size == 0,
all_headers_len + min_result_data_size, all_headers_len + min_result_data_size,
1); 1)))
my_bool success = (*result_block != 0);
if (success)
{ {
Query_cache_block *new_block= *result_block; DBUG_PRINT("warning", ("Can't allocate block for results"));
DBUG_RETURN(FALSE);
}
new_block->n_tables = 0; new_block->n_tables = 0;
new_block->used = 0; new_block->used = min(len, new_block->length);
new_block->type = Query_cache_block::RES_INCOMPLETE; new_block->type = Query_cache_block::RES_INCOMPLETE;
new_block->next = new_block->prev = new_block; new_block->next = new_block->prev = new_block;
Query_cache_result *header = new_block->result(); Query_cache_result *header = new_block->result();
header->parent(query_block); header->parent(query_block);
if (new_block->length < len) DBUG_PRINT("qcache", ("Block len %lu used %lu",
{ new_block->length, new_block->used));
if (prev_block)
double_linked_list_join(prev_block, new_block);
else
*result_block= new_block;
if (new_block->length >= len)
break;
/* /*
We got less memory then we need (no big memory blocks) => We got less memory then we need (no big memory blocks) =>
Continue to allocated more blocks until we got everything we need. Continue to allocated more blocks until we got everything we need.
*/ */
Query_cache_block *next_block; data_len= len - new_block->length;
if ((success = allocate_data_chain(&next_block, prev_block= new_block;
len - new_block->length, } while(1);
query_block, first_block_arg)))
double_linked_list_join(new_block, next_block);
}
if (success)
{
new_block->used = min(len, new_block->length);
DBUG_PRINT("qcache", ("Block len %lu used %lu", DBUG_RETURN(TRUE);
new_block->length, new_block->used));
}
else
DBUG_PRINT("warning", ("Can't allocate block for continue"));
}
else
DBUG_PRINT("warning", ("Can't allocate block for results"));
DBUG_RETURN(success);
} }
/***************************************************************************** /*****************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment