diff options
author | Sergey Vojtovich <svoj@sun.com> | 2010-04-01 15:52:35 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@sun.com> | 2010-04-01 15:52:35 +0400 |
commit | f6beb7656eeb21fbfd8f97e67264bb619cc1b4f9 (patch) | |
tree | b499247523ebef51bad3e83b49758b64370cc7ae /storage | |
parent | 08ed716d85a6d8111938338c121b509036e3daa3 (diff) | |
download | mariadb-git-f6beb7656eeb21fbfd8f97e67264bb619cc1b4f9.tar.gz |
Applying InnoDB snapshot, fixes BUG#49535.
Detailed revision comments:
r6674 | inaam | 2010-02-11 17:54:44 +0200 (Thu, 11 Feb 2010) | 16 lines
branches/zip bug# 49535
This is a backport of r4924.
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
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innodb_plugin/include/mem0mem.h | 3 | ||||
-rw-r--r-- | storage/innodb_plugin/include/mem0mem.ic | 8 | ||||
-rw-r--r-- | storage/innodb_plugin/mem/mem0mem.c | 18 |
3 files changed, 22 insertions, 7 deletions
diff --git a/storage/innodb_plugin/include/mem0mem.h b/storage/innodb_plugin/include/mem0mem.h index 98f8748e529..21d300a8ce5 100644 --- a/storage/innodb_plugin/include/mem0mem.h +++ b/storage/innodb_plugin/include/mem0mem.h @@ -359,6 +359,9 @@ struct mem_block_info_struct { to the heap is also the first block in this list, though it also contains the base node of the list. */ 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 MEM_HEAP_BUF possibly ORed to MEM_HEAP_BTR_SEARCH */ ulint free; /*!< offset in bytes of the first free position for diff --git a/storage/innodb_plugin/include/mem0mem.ic b/storage/innodb_plugin/include/mem0mem.ic index e7080d8c508..cb681c3f724 100644 --- a/storage/innodb_plugin/include/mem0mem.ic +++ b/storage/innodb_plugin/include/mem0mem.ic @@ -579,18 +579,12 @@ mem_heap_get_size( /*==============*/ mem_heap_t* heap) /*!< in: heap */ { - mem_block_t* block; ulint size = 0; ut_ad(mem_heap_check(heap)); - block = heap; - - while (block != NULL) { + size = heap->total_size; - size += mem_block_get_len(block); - block = UT_LIST_GET_NEXT(list, block); - } #ifndef UNIV_HOTBACKUP if (heap->free_block) { size += UNIV_PAGE_SIZE; diff --git a/storage/innodb_plugin/mem/mem0mem.c b/storage/innodb_plugin/mem/mem0mem.c index ccb2fd8a7b4..39bbfc90313 100644 --- a/storage/innodb_plugin/mem/mem0mem.c +++ b/storage/innodb_plugin/mem/mem0mem.c @@ -383,6 +383,20 @@ mem_heap_create_block( mem_block_set_free(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); return(block); @@ -471,6 +485,10 @@ mem_heap_block_free( mem_pool_mutex_exit(); #endif + + ut_ad(heap->total_size >= block->len); + heap->total_size -= block->len; + type = heap->type; len = block->len; block->magic_n = MEM_FREED_BLOCK_MAGIC_N; |