summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2010-10-13 18:15:43 +0300
committerMichael Widenius <monty@askmonty.org>2010-10-13 18:15:43 +0300
commit01672cc026a60d434dc8276908517c9d4fed131d (patch)
treeef048da02ee5591649b6525d560a9c37b6e0a281
parent236141d4f637ee993947270c74ee17a4d4311a2d (diff)
downloadmariadb-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.c2
-rw-r--r--sql/mysqld.cc9
-rw-r--r--storage/maria/ha_maria.cc2
-rw-r--r--storage/maria/ma_delete.c22
-rw-r--r--storage/maria/ma_key_recover.c30
-rw-r--r--storage/maria/ma_loghandler.h3
-rw-r--r--storage/maria/ma_search.c5
-rw-r--r--storage/maria/ma_write.c38
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.", &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
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;