diff options
author | Michael Widenius <monty@askmonty.org> | 2010-10-13 18:15:43 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2010-10-13 18:15:43 +0300 |
commit | 01672cc026a60d434dc8276908517c9d4fed131d (patch) | |
tree | ef048da02ee5591649b6525d560a9c37b6e0a281 | |
parent | 236141d4f637ee993947270c74ee17a4d4311a2d (diff) | |
download | mariadb-git-01672cc026a60d434dc8276908517c9d4fed131d.tar.gz |
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)
-rw-r--r-- | dbug/dbug.c | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 9 | ||||
-rw-r--r-- | storage/maria/ha_maria.cc | 2 | ||||
-rw-r--r-- | storage/maria/ma_delete.c | 22 | ||||
-rw-r--r-- | storage/maria/ma_key_recover.c | 30 | ||||
-rw-r--r-- | storage/maria/ma_loghandler.h | 3 | ||||
-rw-r--r-- | storage/maria/ma_search.c | 5 | ||||
-rw-r--r-- | storage/maria/ma_write.c | 38 |
8 files changed, 62 insertions, 49 deletions
diff --git a/dbug/dbug.c b/dbug/dbug.c index cad7fbb3030..59f7f4e10c5 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -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 { \ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1218ee666e1..5da8d1cdb7f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -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 diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 7447736c48a..2b26de17875 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -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; } diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c index 71ad60b545e..5c04f358b14 100644 --- a/storage/maria/ma_delete.c +++ b/storage/maria/ma_delete.c @@ -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 */ diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index d20875fec3a..6de5253a2dd 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -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; diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h index 8a0b2a1310c..1040d07997a 100644 --- a/storage/maria/ma_loghandler.h +++ b/storage/maria/ma_loghandler.h @@ -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 diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c index a5b9bf18aa9..e1683dad34a 100644 --- a/storage/maria/ma_search.c +++ b/storage/maria/ma_search.c @@ -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) diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index a69799dda4b..7ea73d17b9b 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -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; |