Commit 2f85f78d 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 ab428381
......@@ -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 */
......
......@@ -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;
/*
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 */
};
......
......@@ -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);
}
......
......@@ -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
......
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