Commit 0620e7d9 authored by Michael Widenius's avatar Michael Widenius

Fixes for bugs found by running test case for LP#608369 "Page: 1 Found wrong...

Fixes for bugs found by running test case for LP#608369 "Page: 1 Found wrong page type 0' on CHECK TABLE EXTENDED"
Fixed overflow when using long --debug=xxxxxx line.
Fixed that "mysqld --disable-debug --debug" works.
Ensure that MariaDB doesn't start if the Aria engine didn't start and we are using Aria for temporary tables.
More DBUG_ASSERT() and more info in debug log.


dbug/dbug.c:
  Fixed crash in mysqld caused by an overflow when using long --debug=xxxxxx line
sql/mysqld.cc:
  Fixed that "mysqld --disable-debug --debug" works.
  Documented myisam-recover=OFF option
storage/maria/ha_maria.cc:
  Ensure that MariaDB doesn't start if the Aria engine didn't start and we are using Aria for temporary tables.
storage/maria/ma_delete.c:
  Added missing write of changed key on node page.
  This could fix LP#608369 "Page: 1 Found wrong page type 0' on CHECK TABLE EXTENDED"
  Changed so that we log page numbers (not positions)
  Added KEY_OP_DEBUG_2 log entry to get more debug information into the log
storage/maria/ma_key_recover.c:
  Changed so that we log page numbers (not positions)
  In case of wrong page information after index_redo, dump pages to debug log
storage/maria/ma_loghandler.h:
  Added KEY_OP_DEBUG_2
storage/maria/ma_search.c:
  Changed so that we log page numbers (not positions)
storage/maria/ma_write.c:
  Changed so that we log page numbers (not positions)
parent 9169c02c
......@@ -982,7 +982,7 @@ void _db_pop_()
} while (0)
#define str_to_buf(S) do { \
char_to_buf(','); \
buf=strnmov(buf, (S), len+1); \
buf=strnmov(buf, (S), (uint) (end-buf)); \
if (buf >= end) goto overflow; \
} while (0)
#define list_to_buf(l, f) do { \
......
......@@ -790,7 +790,7 @@ bool mysqld_embedded=1;
static my_bool plugins_are_initialized= FALSE;
#ifndef DBUG_OFF
static const char* default_dbug_option;
static const char* default_dbug_option, *current_dbug_option;
#endif
#ifdef HAVE_LIBWRAP
const char *libwrapName= NULL;
......@@ -6122,8 +6122,8 @@ struct my_option my_long_options[] =
&max_system_variables.wt_timeout_long,
0, GET_ULONG, REQUIRED_ARG, 50000000, 0, ULONG_MAX, 0, 0, 0},
#ifndef DBUG_OFF
{"debug", '#', "Debug log.", &default_dbug_option,
&default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"debug", '#', "Debug log.", &current_dbug_option,
&current_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"debug-crc-break", OPT_DEBUG_CRC,
"Call my_debug_put_break_here() if crc matches this number (for debug).",
&opt_my_crc_dbug_check, &opt_my_crc_dbug_check,
......@@ -6451,7 +6451,7 @@ each time the SQL thread starts.",
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
#endif
{"myisam-recover", OPT_MYISAM_RECOVER,
"Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
"Syntax: myisam-recover=OFF or myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
&myisam_recover_options_str, &myisam_recover_options_str, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
......@@ -8260,6 +8260,7 @@ static int mysql_init_variables(void)
#ifndef DBUG_OFF
default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
"d:t:i:o,/tmp/mysqld.trace");
current_dbug_option= default_dbug_option;
#endif
opt_error_log= IF_WIN(1,0);
#ifdef COMMUNITY_SERVER
......
......@@ -3291,6 +3291,8 @@ static int ha_maria_init(void *p)
/* We can only test for sub paths if my_symlink.c is using realpath */
maria_test_invalid_symlink= test_if_data_home_dir;
#endif
if (res)
maria_hton= 0;
return res ? HA_ERR_INITIALIZATION : 0;
}
......
......@@ -489,7 +489,10 @@ static int d_search(MARIA_HA *info, MARIA_KEY *key, uint32 comp_flag,
}
if (ret_value == 0 && anc_page->size > share->max_index_block_size)
{
/* parent buffer got too big ; We have to split the page */
/*
parent buffer got too big ; We have to split the page.
The | 2 is there to force write of anc page below
*/
save_flag= 3;
ret_value= _ma_split_page(info, key, anc_page,
share->max_index_block_size,
......@@ -595,6 +598,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
endpos= leaf_page->buff+ leaf_page->size;
if (ret_value == 1)
{
/* underflow writes "next_page" to disk */
ret_value= underflow(info, keyinfo, leaf_page, &next_page,
endpos);
if (ret_value == 0 && leaf_page->size >
......@@ -608,6 +612,9 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
}
else
{
if (_ma_write_keypage(&next_page, PAGECACHE_LOCK_LEFT_WRITELOCKED,
DFLT_INIT_HITS))
goto err;
DBUG_PRINT("test",("Inserting of key when deleting"));
if (!_ma_get_last_key(&tmp_key, leaf_page, endpos))
goto err;
......@@ -1451,25 +1458,23 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
enum en_key_debug debug_marker __attribute__((unused)))
{
LSN lsn;
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 2 + 3 + 3 + 6 + 3 + 7];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 5+ 2 + 3 + 3 + 6 + 3 + 7];
uchar *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 7];
uint translog_parts, current_size, extra_length;
uint offset= (uint) (key_pos - ma_page->buff);
MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
my_off_t page;
my_off_t page= ma_page->pos / share->block_size;
DBUG_ENTER("_ma_log_delete");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) (ma_page->pos / share->block_size),
changed_length, move_length));
(ulong) page, changed_length, move_length));
DBUG_ASSERT(share->now_transactional && move_length);
DBUG_ASSERT(offset + changed_length <= ma_page->size);
DBUG_ASSERT(ma_page->org_size - move_length + append_length == ma_page->size);
DBUG_ASSERT(move_length <= ma_page->org_size - share->keypage_header);
/* Store address of new root page */
page= ma_page->pos / share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
log_pos= log_data+ FILEID_STORE_SIZE + PAGE_STORE_SIZE;
current_size= ma_page->org_size;
......@@ -1477,6 +1482,11 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
#ifdef EXTRA_DEBUG_KEY_CHANGES
*log_pos++= KEY_OP_DEBUG;
*log_pos++= debug_marker;
*log_pos++= KEY_OP_DEBUG_2;
int2store(log_pos, ma_page->org_size);
int2store(log_pos+2, ma_page->size);
log_pos+=4;
#endif
/* Store keypage_flag */
......
......@@ -321,15 +321,14 @@ my_bool _ma_log_prefix(MARIA_PAGE *ma_page, uint changed_length,
uchar *log_pos;
uchar *buff= ma_page->buff;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
pgcache_page_no_t page;
MARIA_HA *info= ma_page->info;
pgcache_page_no_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_prefix");
DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
(ulong) ma_page->pos, changed_length, move_length));
(ulong) page, changed_length, move_length));
DBUG_ASSERT(ma_page->size == ma_page->org_size + move_length);
page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
......@@ -412,15 +411,13 @@ my_bool _ma_log_suffix(MARIA_PAGE *ma_page, uint org_length, uint new_length)
int diff;
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
pgcache_page_no_t page;
pgcache_page_no_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_suffix");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
(ulong) page, org_length, new_length));
DBUG_ASSERT(ma_page->size == new_length);
DBUG_ASSERT(ma_page->org_size == org_length);
page= ma_page->pos / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
......@@ -501,12 +498,11 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
uint offset= (uint) (key_pos - buff);
uint max_page_size= info->s->max_index_block_size;
uint translog_parts, current_size;
pgcache_page_no_t page_pos;
pgcache_page_no_t page_pos= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_add");
DBUG_PRINT("enter", ("page: %lu org_page_length: %u changed_length: %u "
"move_length: %d",
(ulong) (ma_page->pos / info->s->block_size),
org_page_length, changed_length,
(ulong) page_pos, org_page_length, changed_length,
move_length));
DBUG_ASSERT(info->s->now_transactional);
DBUG_ASSERT(move_length <= (int) changed_length);
......@@ -519,7 +515,6 @@ my_bool _ma_log_add(MARIA_PAGE *ma_page,
to do the page
*/
log_pos= log_data + FILEID_STORE_SIZE;
page_pos= ma_page->pos / info->s->block_size;
page_store(log_pos, page_pos);
current_size= ma_page->org_size;
log_pos+= PAGE_STORE_SIZE;
......@@ -1083,14 +1078,14 @@ uint _ma_apply_redo_index(MARIA_HA *info,
check_page_length= uint2korr(header);
crc= uint4korr(header+2);
_ma_store_page_used(share, buff, page_length);
DBUG_ASSERT(check_page_length == page_length);
if (crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE,
if (check_page_length != page_length ||
crc != (uint32) my_checksum(0, buff + LSN_STORE_SIZE,
page_length - LSN_STORE_SIZE))
{
DBUG_DUMP("KEY_OP_CHECK bad page", buff, page_length);
if (header + 6 + page_length <= header_end)
if (header + 6 + check_page_length <= header_end)
{
DBUG_DUMP("KEY_OP_CHECK org page", header + 6, page_length);
DBUG_DUMP("KEY_OP_CHECK org page", header + 6, check_page_length);
}
DBUG_ASSERT("crc failure in REDO_INDEX" == 0);
}
......@@ -1109,6 +1104,11 @@ uint _ma_apply_redo_index(MARIA_HA *info,
DBUG_PRINT("redo", ("Debug: %u", (uint) header[0]));
header++;
break;
case KEY_OP_DEBUG_2:
DBUG_PRINT("redo", ("org_page_length: %u new_page_length: %u",
uint2korr(header), uint2korr(header+2)));
header+= 4;
break;
case KEY_OP_MAX_PAGELENGTH:
DBUG_PRINT("redo", ("key_op_max_page_length"));
page_length= max_page_size;
......
......@@ -167,7 +167,8 @@ enum en_key_op
KEY_OP_SET_PAGEFLAG, /* Set pageflag from next byte */
KEY_OP_COMPACT_PAGE, /* Compact key page */
KEY_OP_MAX_PAGELENGTH, /* Set page to max page length */
KEY_OP_DEBUG /* Entry for storing what triggered redo_index */
KEY_OP_DEBUG, /* Entry for storing what triggered redo_index */
KEY_OP_DEBUG_2 /* Entry for pagelengths */
};
enum en_key_debug
......
......@@ -116,8 +116,9 @@ static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
MARIA_PAGE page;
MARIA_PINNED_PAGE *page_link;
DBUG_ENTER("_ma_search");
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
(ulong) pos, nextflag, (ulong) info->cur_row.lastpos));
DBUG_PRINT("enter",("page: %lu nextflag: %u lastpos: %lu",
(ulong) (pos / info->s->block_size),
nextflag, (ulong) info->cur_row.lastpos));
DBUG_EXECUTE("key", _ma_print_key(DBUG_FILE, key););
if (pos == HA_OFFSET_ERROR)
......
......@@ -1246,7 +1246,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
father_key_pos+father_keylength);
left_page= curr_page;
right_page= &next_page;
DBUG_PRINT("info", ("use right page: %lu", (ulong) next_page.pos));
DBUG_PRINT("info", ("use right page: %lu",
(ulong) (next_page.pos / keyinfo->block_length)));
}
else
{
......@@ -1255,7 +1256,8 @@ static int _ma_balance_page(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
next_page.pos= _ma_kpos(share->base.key_reflength,father_key_pos);
left_page= &next_page;
right_page= curr_page;
DBUG_PRINT("info", ("use left page: %lu", (ulong) next_page.pos));
DBUG_PRINT("info", ("use left page: %lu",
(ulong) (next_page.pos / keyinfo->block_length)));
} /* father_key_pos ptr to parting key */
if (_ma_fetch_keypage(&next_page, info, keyinfo, next_page.pos,
......@@ -1871,14 +1873,13 @@ my_bool _ma_log_new(MARIA_PAGE *ma_page, my_bool root_page)
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
MARIA_HA *info= ma_page->info;
MARIA_SHARE *share= info->s;
my_off_t page;
my_off_t page= ma_page->pos / share->block_size;
DBUG_ENTER("_ma_log_new");
DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
DBUG_ASSERT(share->now_transactional);
/* Store address of new root page */
page= ma_page->pos / share->block_size;
page_store(log_data + FILEID_STORE_SIZE, page);
/* Store link to next unused page */
......@@ -1927,10 +1928,10 @@ my_bool _ma_log_change(MARIA_PAGE *ma_page, const uchar *key_pos, uint length,
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 2 + 6 + 7], *log_pos;
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uint offset= (uint) (key_pos - ma_page->buff), translog_parts;
my_off_t page;
MARIA_HA *info= ma_page->info;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_change");
DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) ma_page->pos, length));
DBUG_PRINT("enter", ("page: %lu length: %u", (ulong) page, length));
DBUG_ASSERT(info->s->now_transactional);
DBUG_ASSERT(offset + length <= ma_page->size);
......@@ -2013,16 +2014,17 @@ static my_bool _ma_log_split(MARIA_PAGE *ma_page,
uint offset= (uint) (key_pos - ma_page->buff);
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
my_off_t page;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_split");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
(ulong) page, org_length, new_length));
DBUG_ASSERT(changed_length >= data_length);
DBUG_ASSERT(org_length <= info->s->max_index_block_size);
DBUG_ASSERT(new_length == ma_page->size);
DBUG_ASSERT(org_length == ma_page->org_size);
log_pos= log_data + FILEID_STORE_SIZE;
page= ma_page->pos / info->s->block_size;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
......@@ -2177,16 +2179,16 @@ static my_bool _ma_log_del_prefix(MARIA_PAGE *ma_page,
uint diff_length= org_length + move_length - new_length;
uint translog_parts, extra_length;
MARIA_HA *info= ma_page->info;
my_off_t page;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_del_prefix");
DBUG_PRINT("enter", ("page: %lu org_length: %u new_length: %u",
(ulong) ma_page->pos, org_length, new_length));
(ulong) page, org_length, new_length));
DBUG_ASSERT((int) diff_length > 0);
DBUG_ASSERT(ma_page->org_size == org_length);
DBUG_ASSERT(ma_page->size == new_length);
log_pos= log_data + FILEID_STORE_SIZE;
page= ma_page->pos / info->s->block_size;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
......@@ -2285,10 +2287,10 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 6];
uint key_offset;
uint translog_parts, extra_length;
my_off_t page;
MARIA_HA *info= ma_page->info;
my_off_t page= ma_page->pos / info->s->block_size;
DBUG_ENTER("_ma_log_key_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) ma_page->pos));
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
DBUG_ASSERT(ma_page->size == new_length);
......@@ -2312,8 +2314,6 @@ static my_bool _ma_log_key_middle(MARIA_PAGE *ma_page,
data_deleted_last+= move_length;
}
page= ma_page->pos / info->s->block_size;
/* First log changes to page */
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
......@@ -2408,7 +2408,7 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 4];
uchar log_data[FILEID_STORE_SIZE + PAGE_STORE_SIZE + 3 + 5 + 7], *log_pos;
MARIA_HA *info= ma_page->info;
my_off_t page;
my_off_t page= ma_page->page / info->s->block_size;
uint translog_parts, extra_length;
DBUG_ENTER("_ma_log_middle");
DBUG_PRINT("enter", ("page: %lu", (ulong) page));
......@@ -2416,8 +2416,6 @@ static my_bool _ma_log_middle(MARIA_PAGE *ma_page,
DBUG_ASSERT(ma_page->org_size + data_added_first - data_deleted_last ==
ma_page->size);
page= ma_page->page / info->s->block_size;
log_pos= log_data + FILEID_STORE_SIZE;
page_store(log_pos, page);
log_pos+= PAGE_STORE_SIZE;
......
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