mirror of
https://github.com/MariaDB/server.git
synced 2025-01-20 05:52:27 +01:00
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:
parent
da51d8169b
commit
c72ee5b569
3 changed files with 22 additions and 7 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue