summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@sun.com>2010-04-01 15:52:35 +0400
committerSergey Vojtovich <svoj@sun.com>2010-04-01 15:52:35 +0400
commitf6beb7656eeb21fbfd8f97e67264bb619cc1b4f9 (patch)
treeb499247523ebef51bad3e83b49758b64370cc7ae /storage
parent08ed716d85a6d8111938338c121b509036e3daa3 (diff)
downloadmariadb-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.h3
-rw-r--r--storage/innodb_plugin/include/mem0mem.ic8
-rw-r--r--storage/innodb_plugin/mem/mem0mem.c18
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;