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)
This commit is contained in:
parent
236141d4f6
commit
01672cc026
@ -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.", ¤t_dbug_option,
|
||||
¤t_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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user