Commit 7d259f64 authored by Michael Widenius's avatar Michael Widenius

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
parent fb4d6597
...@@ -1016,7 +1016,7 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size, ...@@ -1016,7 +1016,7 @@ static my_bool allocate_tail(MARIA_FILE_BITMAP *bitmap, uint size,
DBUG_PRINT("enter", ("size: %u", size)); DBUG_PRINT("enter", ("size: %u", size));
LINT_INIT(best_pos); 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) for (; data < end; data += 6)
{ {
...@@ -1732,7 +1732,7 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row, ...@@ -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, row_length= find_where_to_split_row(share, row, extents_length,
max_page_size); max_page_size);
full_page_size= FULL_PAGE_SIZE(share->block_size); full_page_size= MAX_TAIL_SIZE(share->block_size);
position= 0; position= 0;
if (head_length - row_length <= full_page_size) if (head_length - row_length <= full_page_size)
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */ position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
......
...@@ -702,7 +702,8 @@ static int del(MARIA_HA *info, MARIA_KEY *key, ...@@ -702,7 +702,8 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
if (share->now_transactional && if (share->now_transactional &&
_ma_log_add(anc_page, a_length, _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; goto err;
DBUG_RETURN(new_leaf_length <= DBUG_RETURN(new_leaf_length <=
...@@ -971,7 +972,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -971,7 +972,8 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_key_inserted.move_length, anc_key_inserted.move_length,
key_deleted.changed_length), key_deleted.changed_length),
anc_key_inserted.move_length - anc_key_inserted.move_length -
key_deleted.move_length, 1)) key_deleted.move_length, 1,
KEY_OP_DEBUG_LOG_ADD_3))
goto err; goto err;
/* /*
...@@ -1211,7 +1213,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -1211,7 +1213,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
anc_key_inserted.move_length, anc_key_inserted.move_length,
key_deleted.changed_length), key_deleted.changed_length),
anc_key_inserted.move_length - anc_key_inserted.move_length -
key_deleted.move_length, 1)) key_deleted.move_length, 1,KEY_OP_DEBUG_LOG_ADD_4))
goto err; goto err;
/* /*
......
...@@ -488,7 +488,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length) ...@@ -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, my_bool _ma_log_add(MARIA_PAGE *ma_page,
uint org_page_length __attribute__ ((unused)), uint org_page_length __attribute__ ((unused)),
uchar *key_pos, uint changed_length, int move_length, 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; LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 3 + 3 + 3 + 3 + 7 + 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, ...@@ -511,7 +512,7 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
DBUG_ASSERT(move_length <= (int) changed_length); DBUG_ASSERT(move_length <= (int) changed_length);
DBUG_ASSERT(ma_page->org_size == min(org_page_length, max_page_size)); 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(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 Write REDO entry that contains the logical operations we need
...@@ -525,7 +526,7 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, ...@@ -525,7 +526,7 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
#ifdef EXTRA_DEBUG_KEY_CHANGES #ifdef EXTRA_DEBUG_KEY_CHANGES
*log_pos++= KEY_OP_DEBUG; *log_pos++= KEY_OP_DEBUG;
*log_pos++= KEY_OP_DEBUG_LOG_ADD; *log_pos++= debug_marker;
#endif #endif
/* Store keypage_flag */ /* Store keypage_flag */
...@@ -575,11 +576,33 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page, ...@@ -575,11 +576,33 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
log_pos+= 3; log_pos+= 3;
if (move_length) 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; log_pos[0]= KEY_OP_SHIFT;
int2store(log_pos+1, move_length); int2store(log_pos+1, move_length);
log_pos+= 3; log_pos+= 3;
current_size+= move_length; 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; log_pos[0]= KEY_OP_CHANGE;
} }
int2store(log_pos+1, changed_length); int2store(log_pos+1, changed_length);
......
...@@ -70,7 +70,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length, ...@@ -70,7 +70,8 @@ my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length,
uint new_length); uint new_length);
my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos, my_bool _ma_log_add(MARIA_PAGE *page, uint buff_length, uchar *key_pos,
uint changed_length, int move_length, 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, my_bool _ma_log_delete(MARIA_PAGE *page, const uchar *key_pos,
uint changed_length, uint move_length, uint changed_length, uint move_length,
uint append_length, enum en_key_debug debug_marker); uint append_length, enum en_key_debug debug_marker);
......
...@@ -178,18 +178,21 @@ enum en_key_debug ...@@ -178,18 +178,21 @@ enum en_key_debug
KEY_OP_DEBUG_FATHER_CHANGED_1, /* 3 */ KEY_OP_DEBUG_FATHER_CHANGED_1, /* 3 */
KEY_OP_DEBUG_FATHER_CHANGED_2, /* 4 */ KEY_OP_DEBUG_FATHER_CHANGED_2, /* 4 */
KEY_OP_DEBUG_LOG_SPLIT, /* 5 */ KEY_OP_DEBUG_LOG_SPLIT, /* 5 */
KEY_OP_DEBUG_LOG_ADD, /* 6 */ KEY_OP_DEBUG_LOG_ADD_1, /* 6 */
KEY_OP_DEBUG_LOG_PREFIX_1, /* 7 */ KEY_OP_DEBUG_LOG_ADD_2, /* 7 */
KEY_OP_DEBUG_LOG_PREFIX_2, /* 8 */ KEY_OP_DEBUG_LOG_ADD_3, /* 8 */
KEY_OP_DEBUG_LOG_PREFIX_3, /* 9 */ KEY_OP_DEBUG_LOG_ADD_4, /* 9 */
KEY_OP_DEBUG_LOG_PREFIX_4, /* 10 */ KEY_OP_DEBUG_LOG_PREFIX_1, /* 10 */
KEY_OP_DEBUG_LOG_PREFIX_5, /* 11 */ KEY_OP_DEBUG_LOG_PREFIX_2, /* 11 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 12 */ KEY_OP_DEBUG_LOG_PREFIX_3, /* 12 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 13 */ KEY_OP_DEBUG_LOG_PREFIX_4, /* 13 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_3, /* 14 */ KEY_OP_DEBUG_LOG_PREFIX_5, /* 14 */
KEY_OP_DEBUG_LOG_DEL_CHANGE_RT, /* 15 */ KEY_OP_DEBUG_LOG_DEL_CHANGE_1, /* 15 */
KEY_OP_DEBUG_LOG_DEL_PREFIX, /* 16 */ KEY_OP_DEBUG_LOG_DEL_CHANGE_2, /* 16 */
KEY_OP_DEBUG_LOG_MIDDLE /* 17 */ 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 */
}; };
......
...@@ -59,7 +59,8 @@ int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page, ...@@ -59,7 +59,8 @@ int maria_rtree_add_key(const MARIA_KEY *key, MARIA_PAGE *page,
page_store_size(share, page); page_store_size(share, page);
if (share->now_transactional && if (share->now_transactional &&
_ma_log_add(page, key_pos - page->buff, _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(-1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -768,6 +768,10 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, ...@@ -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_PRINT("enter",("key_pos: 0x%lx", (ulong) key_pos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key);); 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; org_anc_length= a_length= anc_page->size;
nod_flag= anc_page->node; 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 ...@@ -887,7 +891,8 @@ ChangeSet@1.2562, 2008-04-09 07:41:40+02:00, serg@janus.mylan +9 -0
{ {
if (share->now_transactional && if (share->now_transactional &&
_ma_log_add(anc_page, org_anc_length, _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(-1);
} }
DBUG_RETURN(0); /* There is room on page */ 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 ...@@ -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, father_page, father_key_pos,
&s_temp)); &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_pos, s_temp.changed_length, t_length,
key_buff, insert_last)); key_buff, insert_last));
} /* _ma_insert */ } /* _ma_insert */
...@@ -1971,7 +1978,8 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length, ...@@ -1971,7 +1978,8 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
@fn _ma_log_split() @fn _ma_log_split()
@param @param
ma_page Page that is changed 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 new_length New length of page
key_pos Where key is inserted on page (may be 0 if no key) key_pos Where key is inserted on page (may be 0 if no key)
key_length Number of bytes changed at key_pos key_length Number of bytes changed at key_pos
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment