From 7d259f649531885cfef6896a1762c356c6cc5754 Mon Sep 17 00:00:00 2001 From: Michael Widenius <monty@askmonty.org> Date: Thu, 7 Oct 2010 12:51:34 +0300 Subject: [PATCH] Fixes some bug in Aria recovery: - _ma_apply_redo_index: Assertion `page_offset != 0 && page_offset + length <= page_length' failed Fixes one bug and one log assert when inserting rows: - _ma_log_split: Assertion `org_length <= info->s->max_index_block_size' failed - write_block_record: Assertion '(data_length < MAX_TAIL_SIZE(block_size)' failed Mark in recovery log where _ma_log_add() calls was done (for better debugging). storage/maria/ma_bitmap.c: Don't write a head part on a tail page. (Caused an assert in write_block_record()) storage/maria/ma_delete.c: Mark in recovery log where _ma_log_add() calls was done storage/maria/ma_key_recover.c: Mark in recovery log where _ma_log_add() calls was done Fixed not handled logging case for overfull index pages. storage/maria/ma_key_recover.h: Mark in recovery log where _ma_log_add() calls was done storage/maria/ma_loghandler.h: Mark in recovery log where _ma_log_add() calls was done storage/maria/ma_rt_key.c: Mark in recovery log where _ma_log_add() calls was done storage/maria/ma_write.c: Mark in recovery log where _ma_log_add() calls was done. Fixed wrong call to _ma_split_page() for overfull pages --- storage/maria/ma_bitmap.c | 4 ++-- storage/maria/ma_delete.c | 8 +++++--- storage/maria/ma_key_recover.c | 29 ++++++++++++++++++++++++++--- storage/maria/ma_key_recover.h | 3 ++- storage/maria/ma_loghandler.h | 27 +++++++++++++++------------ storage/maria/ma_rt_key.c | 3 ++- storage/maria/ma_write.c | 14 +++++++++++--- 7 files changed, 63 insertions(+), 25 deletions(-) diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c index 4f37d7b9a1f..d8b7a9b9a99 100644 --- a/storage/maria/ma_bitmap.c +++ b/storage/maria/ma_bitmap.c @@ -1016,7 +1016,7 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size, DBUG_PRINT("enter", ("size: %u", size)); LINT_INIT(best_pos); - DBUG_ASSERT(size <= FULL_PAGE_SIZE(bitmap->block_size)); + DBUG_ASSERT(size <= MAX_TAIL_SIZE(bitmap->block_size)); for (; data < end; data += 6) { @@ -1732,7 +1732,7 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row, row_length= find_where_to_split_row(share, row, extents_length, max_page_size); - full_page_size= FULL_PAGE_SIZE(share->block_size); + full_page_size= MAX_TAIL_SIZE(share->block_size); position= 0; if (head_length - row_length <= full_page_size) position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */ diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index 2420cac0e93..71ad60b545e 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -702,7 +702,8 @@ static int del(MARIA_HA *info, MARIA_KEY *key, if (share->now_transactional && _ma_log_add(anc_page, a_length, - key_start, s_temp.changed_length, s_temp.move_length, 1)) + key_start, s_temp.changed_length, s_temp.move_length, 1, + KEY_OP_DEBUG_LOG_ADD_2)) goto err; DBUG_RETURN(new_leaf_length <= @@ -971,7 +972,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, anc_key_inserted.move_length, key_deleted.changed_length), anc_key_inserted.move_length - - key_deleted.move_length, 1)) + key_deleted.move_length, 1, + KEY_OP_DEBUG_LOG_ADD_3)) goto err; /* @@ -1211,7 +1213,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, anc_key_inserted.move_length, key_deleted.changed_length), anc_key_inserted.move_length - - key_deleted.move_length, 1)) + key_deleted.move_length, 1,KEY_OP_DEBUG_LOG_ADD_4)) goto err; /* diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index 1a61731e817..d20875fec3a 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -488,7 +488,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length) my_bool _ma_log_add(MARIA_PAGE *ma_page, uint org_page_length __attribute__ ((unused)), uchar *key_pos, uint changed_length, int move_length, - my_bool handle_overflow __attribute__ ((unused))) + my_bool handle_overflow __attribute__ ((unused)), + enum en_key_debug debug_marker __attribute__((unused))) { LSN lsn; uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 3 + 3 + 3 + 3 + 7 + @@ -511,7 +512,7 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, DBUG_ASSERT(move_length <= (int) changed_length); DBUG_ASSERT(ma_page->org_size == min(org_page_length, max_page_size)); DBUG_ASSERT(ma_page->size == org_page_length + move_length); - DBUG_ASSERT(offset < max_page_size); + DBUG_ASSERT(offset <= ma_page->org_size); /* Write REDO entry that contains the logical operations we need @@ -525,7 +526,7 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, #ifdef EXTRA_DEBUG_KEY_CHANGES *log_pos++= KEY_OP_DEBUG; - *log_pos++= KEY_OP_DEBUG_LOG_ADD; + *log_pos++= debug_marker; #endif /* Store keypage_flag */ @@ -575,11 +576,33 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, log_pos+= 3; if (move_length) { + if (move_length < 0) + { + DBUG_ASSERT(offset - move_length <= org_page_length); + if (offset - move_length > current_size) + { + /* + Truncate to end of page. We will add data to it from + the page buffer below + */ + move_length= (int) offset - (int) current_size; + } + } log_pos[0]= KEY_OP_SHIFT; int2store(log_pos+1, move_length); log_pos+= 3; current_size+= move_length; } + /* + Handle case where page was shortend but 'changed_length' goes over + 'current_size'. This can only happen when there was a page overflow + and we will below add back the overflow part + */ + if (offset + changed_length > current_size) + { + DBUG_ASSERT(offset + changed_length <= ma_page->size); + changed_length= current_size - offset; + } log_pos[0]= KEY_OP_CHANGE; } int2store(log_pos+1, changed_length); diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h index 3fdb045ee40..d6b69010d5d 100644 --- a/storage/maria/ma_key_recover.h +++ b/storage/maria/ma_key_recover.h @@ -70,7 +70,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length, uint new_length); my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos, uint changed_length, int move_length, - my_bool handle_overflow); + my_bool handle_overflow, + enum en_key_debug debug_marker); my_bool _ma_log_delete(MARIA_PAGE *page, const uchar *key_pos, uint changed_length, uint move_length, uint append_length, enum en_key_debug debug_marker); diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index 8e04164a81a..8a0b2a1310c 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -178,18 +178,21 @@ enum en_key_debug KEY_OP_DEBUG_FATHER_CHANGED_1, /* 3 */ KEY_OP_DEBUG_FATHER_CHANGED_2, /* 4 */ KEY_OP_DEBUG_LOG_SPLIT, /* 5 */ - KEY_OP_DEBUG_LOG_ADD, /* 6 */ - KEY_OP_DEBUG_LOG_PREFIX_1, /* 7 */ - KEY_OP_DEBUG_LOG_PREFIX_2, /* 8 */ - KEY_OP_DEBUG_LOG_PREFIX_3, /* 9 */ - KEY_OP_DEBUG_LOG_PREFIX_4, /* 10 */ - KEY_OP_DEBUG_LOG_PREFIX_5, /* 11 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 12 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 13 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 14 */ - KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 15 */ - KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 16 */ - KEY_OP_DEBUG_LOG_MIDDLE /* 17 */ + KEY_OP_DEBUG_LOG_ADD_1, /* 6 */ + KEY_OP_DEBUG_LOG_ADD_2, /* 7 */ + KEY_OP_DEBUG_LOG_ADD_3, /* 8 */ + KEY_OP_DEBUG_LOG_ADD_4, /* 9 */ + KEY_OP_DEBUG_LOG_PREFIX_1, /* 10 */ + KEY_OP_DEBUG_LOG_PREFIX_2, /* 11 */ + KEY_OP_DEBUG_LOG_PREFIX_3, /* 12 */ + KEY_OP_DEBUG_LOG_PREFIX_4, /* 13 */ + KEY_OP_DEBUG_LOG_PREFIX_5, /* 14 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 15 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 16 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 17 */ + KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 18 */ + KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 19 */ + KEY_OP_DEBUG_LOG_MIDDLE /* 20 */ }; diff --git a/storage/maria/ma_rt_key.c b/storage/maria/ma_rt_key.c index 2e204990a3b..fa173605cd3 100644 --- a/storage/maria/ma_rt_key.c +++ b/storage/maria/ma_rt_key.c @@ -59,7 +59,8 @@ int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page, page_store_size(share, page); if (share->now_transactional && _ma_log_add(page, key_pos - page->buff, - key_pos, tot_key_length, tot_key_length, 0)) + key_pos, tot_key_length, tot_key_length, 0, + KEY_OP_DEBUG_LOG_ADD_1)) DBUG_RETURN(-1); DBUG_RETURN(0); } diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index c6718299d17..a69799dda4b 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -768,6 +768,10 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, DBUG_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos)); DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key);); + /* + Note that anc_page->size can be bigger then block_size in case of + delete key that caused increase of page length + */ org_anc_length= a_length= anc_page->size; nod_flag= anc_page->node; @@ -887,7 +891,8 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0 { if (share->now_transactional && _ma_log_add(anc_page, org_anc_length, - key_pos, s_temp.changed_length, t_length, 1)) + key_pos, s_temp.changed_length, t_length, 1, + KEY_OP_DEBUG_LOG_ADD_1)) DBUG_RETURN(-1); } DBUG_RETURN(0); /* There is room on page */ @@ -911,7 +916,9 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0 father_page, father_key_pos, &s_temp)); } - DBUG_RETURN(_ma_split_page(info, key, anc_page, org_anc_length, + DBUG_RETURN(_ma_split_page(info, key, anc_page, + min(org_anc_length, + info->s->max_index_block_size), key_pos, s_temp.changed_length, t_length, key_buff, insert_last)); } /* _ma_insert */ @@ -1971,7 +1978,8 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length, @fn _ma_log_split() @param ma_page Page that is changed - org_length Original length of page + org_length Original length of page. Can be bigger than block_size + for block that overflowed new_length New length of page key_pos Where key is inserted on page (may be 0 if no key) key_length Number of bytes changed at key_pos -- 2.30.9