branches/innodb+

mem_heap_get_size() scans all allocated blocks to calculate the total
size of the heap. This patch introduces a new, total_size, field in
mem_block_info_struct. This field is valid only for base block 
(i.e.: the first block allocated for the heap) and is set to
ULINT_UNDEFINED in other blocks.
This considerably improves the performance of redo scan during recovery.

rb://108 issue#216

Approved by: Heikki
This commit is contained in:
inaam 2009-04-30 13:11:10 +00:00
parent da51d8169b
commit c72ee5b569
3 changed files with 22 additions and 7 deletions

View file

@ -369,6 +369,9 @@ struct mem_block_info_struct {
to the heap is also the first block in this list, to the heap is also the first block in this list,
though it also contains the base node of the list. */ though it also contains the base node of the list. */
ulint len; /* physical length of this block in bytes */ ulint len; /* physical length of this block in bytes */
ulint total_size; /* physical length in bytes of all blocks
in the heap. This is defined only in the base
node and is set to ULINT_UNDEFINED in others. */
ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or ulint type; /* type of heap: MEM_HEAP_DYNAMIC, or
MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */ MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */
ulint free; /* offset in bytes of the first free position for ulint free; /* offset in bytes of the first free position for

View file

@ -583,18 +583,12 @@ mem_heap_get_size(
/*==============*/ /*==============*/
mem_heap_t* heap) /* in: heap */ mem_heap_t* heap) /* in: heap */
{ {
mem_block_t* block;
ulint size = 0; ulint size = 0;
ut_ad(mem_heap_check(heap)); ut_ad(mem_heap_check(heap));
block = heap; size = heap->total_size;
while (block != NULL) {
size += mem_block_get_len(block);
block = UT_LIST_GET_NEXT(list, block);
}
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
if (heap->free_block) { if (heap->free_block) {
size += UNIV_PAGE_SIZE; size += UNIV_PAGE_SIZE;

View file

@ -405,6 +405,20 @@ mem_heap_create_block(
mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE); mem_block_set_free(block, MEM_BLOCK_HEADER_SIZE);
mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE); mem_block_set_start(block, MEM_BLOCK_HEADER_SIZE);
if (UNIV_UNLIKELY(heap == NULL)) {
/* This is the first block of the heap. The field
total_size should be initialized here */
block->total_size = len;
} else {
/* Not the first allocation for the heap. This block's
total_length field should be set to undefined. */
ut_d(block->total_size = ULINT_UNDEFINED);
UNIV_MEM_INVALID(&block->total_size,
sizeof block->total_size);
heap->total_size += len;
}
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len); ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);
return(block); return(block);
@ -494,6 +508,10 @@ mem_heap_block_free(
mem_pool_mutex_exit(); mem_pool_mutex_exit();
#endif #endif
ut_ad(heap->total_size >= block->len);
heap->total_size -= block->len;
type = heap->type; type = heap->type;
len = block->len; len = block->len;
block->magic_n = MEM_FREED_BLOCK_MAGIC_N; block->magic_n = MEM_FREED_BLOCK_MAGIC_N;