diff options
author | unknown <heikki@hundin.mysql.fi> | 2002-08-02 23:16:19 +0300 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2002-08-02 23:16:19 +0300 |
commit | 0ebb78e8ef8fa1fc77ac8c9caeb8cbd37337030a (patch) | |
tree | 79d62af7e6f5f927672de74cbb469640fe4ff3bd /innobase | |
parent | dd764d999ee270d3e3ad5e14881b7b16c247d762 (diff) | |
download | mariadb-git-0ebb78e8ef8fa1fc77ac8c9caeb8cbd37337030a.tar.gz |
Many files:
Merge InnoDB-3.23.52c
ha_innobase.cc:
Test the ref length sanity also in the production version
sql/ha_innobase.cc:
Test the ref length sanity also in the production version
innobase/btr/btr0cur.c:
Merge InnoDB-3.23.52c
innobase/buf/buf0buf.c:
Merge InnoDB-3.23.52c
innobase/buf/buf0lru.c:
Merge InnoDB-3.23.52c
innobase/ha/ha0ha.c:
Merge InnoDB-3.23.52c
innobase/log/log0recv.c:
Merge InnoDB-3.23.52c
innobase/mtr/mtr0log.c:
Merge InnoDB-3.23.52c
innobase/os/os0file.c:
Merge InnoDB-3.23.52c
innobase/page/page0cur.c:
Merge InnoDB-3.23.52c
innobase/include/btr0btr.h:
Merge InnoDB-3.23.52c
innobase/include/dyn0dyn.h:
Merge InnoDB-3.23.52c
innobase/include/log0recv.h:
Merge InnoDB-3.23.52c
innobase/include/buf0buf.ic:
Merge InnoDB-3.23.52c
innobase/include/log0log.ic:
Merge InnoDB-3.23.52c
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/btr/btr0cur.c | 8 | ||||
-rw-r--r-- | innobase/buf/buf0buf.c | 2 | ||||
-rw-r--r-- | innobase/buf/buf0lru.c | 38 | ||||
-rw-r--r-- | innobase/ha/ha0ha.c | 14 | ||||
-rw-r--r-- | innobase/include/btr0btr.h | 8 | ||||
-rw-r--r-- | innobase/include/buf0buf.ic | 37 | ||||
-rw-r--r-- | innobase/include/dyn0dyn.h | 8 | ||||
-rw-r--r-- | innobase/include/log0log.ic | 2 | ||||
-rw-r--r-- | innobase/include/log0recv.h | 3 | ||||
-rw-r--r-- | innobase/log/log0recv.c | 162 | ||||
-rw-r--r-- | innobase/mtr/mtr0log.c | 37 | ||||
-rw-r--r-- | innobase/os/os0file.c | 2 | ||||
-rw-r--r-- | innobase/page/page0cur.c | 24 |
13 files changed, 258 insertions, 87 deletions
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 6caf940b34d..ada7e482b7e 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -808,7 +808,7 @@ btr_cur_optimistic_insert( if (!dtuple_check_typed_no_assert(entry)) { fprintf(stderr, -"InnoDB: Error in a tuple to insert into table %s index %s\n", +"InnoDB: Error in a tuple to insert into table %lu index %s\n", index->table_name, index->name); } @@ -1213,6 +1213,8 @@ btr_cur_parse_update_in_place( rec_offset = mach_read_from_2(ptr); ptr += 2; + ut_a(rec_offset <= UNIV_PAGE_SIZE); + heap = mem_heap_create(256); ptr = row_upd_index_parse(ptr, end_ptr, heap, &update); @@ -1977,6 +1979,8 @@ btr_cur_parse_del_mark_set_clust_rec( offset = mach_read_from_2(ptr); ptr += 2; + ut_a(offset <= UNIV_PAGE_SIZE); + if (page) { rec = page + offset; @@ -2127,6 +2131,8 @@ btr_cur_parse_del_mark_set_sec_rec( offset = mach_read_from_2(ptr); ptr += 2; + ut_a(offset <= UNIV_PAGE_SIZE); + if (page) { rec = page + offset; diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index 9cd4197165c..a447f9692a7 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -286,7 +286,7 @@ buf_page_print( ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Page dump in ascii and hex (%lu bytes):\n%s", - (unsigned long) UNIV_PAGE_SIZE, buf); + (ulint)UNIV_PAGE_SIZE, buf); fprintf(stderr, "InnoDB: End of page dump\n"); mem_free(buf); diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index a2996eefca9..ffdc58f2224 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -204,6 +204,44 @@ buf_LRU_get_free_block(void) loop: mutex_enter(&(buf_pool->mutex)); + if (UT_LIST_GET_LEN(buf_pool->free) + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 10) { + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: ERROR: over 9 / 10 of the buffer pool is occupied by\n" +"InnoDB: lock heaps or the adaptive hash index!\n" +"InnoDB: We intentionally generate a seg fault to print a stack trace\n" +"InnoDB: on Linux!\n"); + + ut_a(0); + + } else if (UT_LIST_GET_LEN(buf_pool->free) + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) { + + /* Over 80 % of the buffer pool is occupied by lock heaps + or the adaptive hash index. This may be a memory leak! */ + + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: WARNING: over 4 / 5 of the buffer pool is occupied by\n" +"InnoDB: lock heaps or the adaptive hash index! Check that your\n" +"InnoDB: transactions do not set too many row locks. Starting InnoDB\n" +"InnoDB: Monitor to print diagnostics, including lock heap and hash index\n" +"InnoDB: sizes.\n"); + + srv_print_innodb_monitor = TRUE; + + } else if (UT_LIST_GET_LEN(buf_pool->free) + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) { + + /* Switch off the InnoDB Monitor; this is a simple way + to stop the monitor if the situation becomes less urgent, + but may also surprise users! */ + + srv_print_innodb_monitor = FALSE; + } + if (buf_pool->LRU_flush_ended > 0) { mutex_exit(&(buf_pool->mutex)); diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index acde236bb2f..4489b25ec2b 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -298,6 +298,7 @@ ha_print_info( ulint cells = 0; ulint len = 0; ulint max_len = 0; + ulint n_bufs; ulint i; if (buf_end - buf < 200) { @@ -339,7 +340,16 @@ ha_print_info( "Hash table size %lu, used cells %lu", hash_get_n_cells(table), cells); if (table->heaps == NULL && table->heap != NULL) { - buf += sprintf(buf, -", node heap has %lu buffer(s)\n", UT_LIST_GET_LEN(table->heap->base)); + + /* This calculation is intended for the adaptive hash + index: how many buffer frames we have reserved? */ + + n_bufs = UT_LIST_GET_LEN(table->heap->base) - 1; + + if (table->heap->free_block) { + n_bufs++; + } + + buf += sprintf(buf, ", node heap has %lu buffer(s)\n", n_bufs); } } diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index 1b48eaeb4b2..f66ad3639d4 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -313,14 +313,6 @@ btr_discard_page( btr_cur_t* cursor, /* in: cursor on the page to discard: not on the root page */ mtr_t* mtr); /* in: mtr */ -/************************************************************************ -Declares the latching order level for the page latch in the debug version. */ - -void -btr_declare_page_latch( -/*===================*/ - page_t* page, /* in: page */ - ibool leaf); /* in: TRUE if a leaf */ /******************************************************************** Parses the redo log record for setting an index record as the predefined minimum record. */ diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index 50248a7b2da..51e2541e04d 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -211,8 +211,15 @@ buf_block_align( block = buf_pool_get_nth_block(buf_pool, ((ulint)(ptr - frame_zero)) >> UNIV_PAGE_SIZE_SHIFT); - ut_a(block >= buf_pool->blocks); - ut_a(block < buf_pool->blocks + buf_pool->max_size); + if (block < buf_pool->blocks + || block >= buf_pool->blocks + buf_pool->max_size) { + + fprintf(stderr, +"InnoDB: Error: trying to access a stray pointer %lx\n" +"InnoDB: buf pool start is at %lx, number of pages %lu\n", (ulint)ptr, + (ulint)frame_zero, buf_pool->max_size); + ut_a(0); + } return(block); } @@ -238,8 +245,15 @@ buf_block_align_low( block = buf_pool_get_nth_block(buf_pool, ((ulint)(ptr - frame_zero)) >> UNIV_PAGE_SIZE_SHIFT); - ut_a(block >= buf_pool->blocks); - ut_a(block < buf_pool->blocks + buf_pool->max_size); + if (block < buf_pool->blocks + || block >= buf_pool->blocks + buf_pool->max_size) { + + fprintf(stderr, +"InnoDB: Error: trying to access a stray pointer %lx\n" +"InnoDB: buf pool start is at %lx, number of pages %lu\n", (ulint)ptr, + (ulint)frame_zero, buf_pool->max_size); + ut_a(0); + } return(block); } @@ -259,10 +273,17 @@ buf_frame_align( frame = ut_align_down(ptr, UNIV_PAGE_SIZE); - ut_a((ulint)frame - >= (ulint)(buf_pool_get_nth_block(buf_pool, 0)->frame)); - ut_a((ulint)frame <= (ulint)(buf_pool_get_nth_block(buf_pool, - buf_pool->max_size - 1)->frame)); + if (((ulint)frame + < (ulint)(buf_pool->frame_zero)) + || ((ulint)frame > (ulint)(buf_pool_get_nth_block(buf_pool, + buf_pool->max_size - 1)->frame))) { + fprintf(stderr, +"InnoDB: Error: trying to access a stray pointer %lx\n" +"InnoDB: buf pool start is at %lx, number of pages %lu\n", (ulint)ptr, + (ulint)(buf_pool->frame_zero), buf_pool->max_size); + ut_a(0); + } + return(frame); } diff --git a/innobase/include/dyn0dyn.h b/innobase/include/dyn0dyn.h index 49a1a4c6129..cca302994c1 100644 --- a/innobase/include/dyn0dyn.h +++ b/innobase/include/dyn0dyn.h @@ -125,14 +125,6 @@ dyn_block_get_data( /*===============*/ /* out: pointer to data */ dyn_block_t* block); /* in: dyn array block */ -/************************************************************************ -Gets the next block in a dyn array. */ - -dyn_block_t* -dyn_block_get_next( -/*===============*/ - /* out: pointer to next, NULL if end of list */ - dyn_block_t* block); /* in: dyn array block */ /************************************************************ Pushes n bytes to a dyn array. */ UNIV_INLINE diff --git a/innobase/include/log0log.ic b/innobase/include/log0log.ic index 9167246fe45..8de239df0bd 100644 --- a/innobase/include/log0log.ic +++ b/innobase/include/log0log.ic @@ -207,7 +207,7 @@ log_block_calc_checksum( for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) { sum = sum & 0x7FFFFFFF; - sum += ((ulint)(*(block + i))) << sh; + sum += (((ulint)(*(block + i))) << sh) + (ulint)(*(block + i)); sh++; if (sh > 24) { sh = 0; diff --git a/innobase/include/log0recv.h b/innobase/include/log0recv.h index 65f80deee93..baa2ba50c7d 100644 --- a/innobase/include/log0recv.h +++ b/innobase/include/log0recv.h @@ -316,7 +316,8 @@ struct recv_sys_struct{ ibool found_corrupt_log; /* this is set to TRUE if we during log scan find a corrupt log block, or a corrupt - log record */ + log record, or there is a log parsing + buffer overflow */ log_group_t* archive_group; /* in archive recovery: the log group whose archive is read */ diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 62031005e05..1223f9b6041 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -58,13 +58,17 @@ yet: the variable name is misleading */ ibool recv_no_ibuf_operations = FALSE; -/* the following counter is used to decide when to print info on +/* The following counter is used to decide when to print info on log scan */ ulint recv_scan_print_counter = 0; ibool recv_is_from_backup = FALSE; ibool recv_is_making_a_backup = FALSE; +ulint recv_previous_parsed_rec_type = 999999; +ulint recv_previous_parsed_rec_offset = 0; +ulint recv_previous_parsed_rec_is_multi = 0; + /************************************************************ Creates the recovery system. */ @@ -695,7 +699,7 @@ byte* recv_parse_or_apply_log_rec_body( /*=============================*/ /* out: log record end, NULL if not a complete - record, or a corrupt record */ + record */ byte type, /* in: type */ byte* ptr, /* in: pointer to a buffer */ byte* end_ptr,/* in: pointer to the buffer end */ @@ -770,15 +774,6 @@ recv_parse_or_apply_log_rec_body( new_ptr = mlog_parse_string(ptr, end_ptr, page); } else { new_ptr = NULL; - - fprintf(stderr, - "InnoDB: WARNING: the log file may have been corrupt and it\n" - "InnoDB: is possible that the log scan did not proceed\n" - "InnoDB: far enough in recovery. Please run CHECK TABLE\n" - "InnoDB: on your InnoDB tables to check that they are ok!\n" - "InnoDB: Corrupt log record type %lu\n, lsn %lu %lu\n", - (ulint)type, ut_dulint_get_high(recv_sys->recovered_lsn), - ut_dulint_get_low(recv_sys->recovered_lsn)); recv_sys->found_corrupt_log = TRUE; } @@ -1651,7 +1646,7 @@ ulint recv_parse_log_rec( /*===============*/ /* out: length of the record, or 0 if the record was - not complete or it was corrupt */ + not complete */ byte* ptr, /* in: pointer to a buffer */ byte* end_ptr,/* in: pointer to the buffer end */ byte* type, /* out: type */ @@ -1691,16 +1686,6 @@ recv_parse_log_rec( /* Check that space id and page_no are sensible */ if (*space != 0 || *page_no > 0x8FFFFFFF) { - fprintf(stderr, - "InnoDB: WARNING: the log file may have been corrupt and it\n" - "InnoDB: is possible that the log scan did not proceed\n" - "InnoDB: far enough in recovery. Please run CHECK TABLE\n" - "InnoDB: on your InnoDB tables to check that they are ok!\n" - "InnoDB: Corrupt log record type %lu, space id %lu, page no %lu\n", - "InnoDB: lsn %lu %lu\n", - (ulint)(*type), *space, *page_no, - ut_dulint_get_high(recv_sys->recovered_lsn), - ut_dulint_get_low(recv_sys->recovered_lsn)); recv_sys->found_corrupt_log = TRUE; @@ -1767,14 +1752,70 @@ recv_check_incomplete_log_recs( } /*********************************************************** +Prints diagnostic info of corrupt log. */ +static +void +recv_report_corrupt_log( +/*====================*/ + byte* ptr, /* in: pointer to corrupt log record */ + byte type, /* in: type of the record */ + ulint space, /* in: space id, this may also be garbage */ + ulint page_no)/* in: page number, this may also be garbage */ +{ + char* err_buf; + + fprintf(stderr, +"InnoDB: ############### CORRUPT LOG RECORD FOUND\n" +"InnoDB: Log record type %lu, space id %lu, page number %lu\n" +"InnoDB: Log parsing proceeded successfully up to %lu %lu\n", + (ulint)type, space, page_no, + ut_dulint_get_high(recv_sys->recovered_lsn), + ut_dulint_get_low(recv_sys->recovered_lsn)); + + err_buf = ut_malloc(1000000); + + fprintf(stderr, +"InnoDB: Previous log record type %lu, is multi %lu\n" +"InnoDB: Recv offset %lu, prev %lu\n", + recv_previous_parsed_rec_type, + recv_previous_parsed_rec_is_multi, + ptr - recv_sys->buf, + recv_previous_parsed_rec_offset); + + if ((ulint)(ptr - recv_sys->buf + 100) + > recv_previous_parsed_rec_offset + && (ulint)(ptr - recv_sys->buf + 100 + - recv_previous_parsed_rec_offset) + < 200000) { + + ut_sprintf_buf(err_buf, + recv_sys->buf + recv_previous_parsed_rec_offset - 100, + ptr - recv_sys->buf + 200 - + recv_previous_parsed_rec_offset); + fprintf(stderr, +"InnoDB: Hex dump of corrupt log starting 100 bytes before the start\n" +"InnoDB: of the previous log rec,\n" +"InnoDB: and ending 100 bytes after the start of the corrupt rec:\n%s\n", + err_buf); + } + + ut_free(err_buf); + + fprintf(stderr, + "InnoDB: WARNING: the log file may have been corrupt and it\n" + "InnoDB: is possible that the log scan did not proceed\n" + "InnoDB: far enough in recovery! Please run CHECK TABLE\n" + "InnoDB: on your InnoDB tables to check that they are ok!\n"); +} + +/*********************************************************** Parses log records from a buffer and stores them to a hash table to wait merging to file pages. */ static ibool recv_parse_log_recs( /*================*/ - /* out: TRUE if the hash table of parsed log - records became full */ + /* out: currently always returns FALSE */ ibool store_to_hash) /* in: TRUE if the records should be stored to the hash table; this is set to FALSE if just debug checking is needed */ @@ -1791,7 +1832,6 @@ recv_parse_log_recs( ulint page_no; byte* body; ulint n_recs; - char err_buf[2500]; ut_ad(mutex_own(&(log_sys->mutex))); ut_ad(!ut_dulint_is_zero(recv_sys->parse_start_lsn)); @@ -1814,17 +1854,11 @@ loop: len = recv_parse_log_rec(ptr, end_ptr, &type, &space, &page_no, &body); - if (len == 0) { + if (len == 0 || recv_sys->found_corrupt_log) { if (recv_sys->found_corrupt_log) { - - ut_sprintf_buf(err_buf, - recv_sys->buf + ut_calc_align_down( - recv_sys->recovered_offset, - OS_FILE_LOG_BLOCK_SIZE) - 8, - OS_FILE_LOG_BLOCK_SIZE + 16); - - fprintf(stderr, -"InnoDB: hex dump of a corrupt log segment: %s\n", err_buf); + + recv_report_corrupt_log(ptr, + type, space, page_no); } return(FALSE); @@ -1841,6 +1875,10 @@ loop: return(FALSE); } + recv_previous_parsed_rec_type = (ulint)type; + recv_previous_parsed_rec_offset = recv_sys->recovered_offset; + recv_previous_parsed_rec_is_multi = 0; + recv_sys->recovered_offset += len; recv_sys->recovered_lsn = new_recovered_lsn; @@ -1879,22 +1917,22 @@ loop: for (;;) { len = recv_parse_log_rec(ptr, end_ptr, &type, &space, &page_no, &body); - if (len == 0) { - - if (recv_sys->found_corrupt_log) { - ut_sprintf_buf(err_buf, - recv_sys->buf + ut_calc_align_down( - recv_sys->recovered_offset, - OS_FILE_LOG_BLOCK_SIZE) - 8, - OS_FILE_LOG_BLOCK_SIZE + 16); - - fprintf(stderr, -"InnoDB: hex dump of a corrupt log segment: %s\n", err_buf); - } + if (len == 0 || recv_sys->found_corrupt_log) { + + if (recv_sys->found_corrupt_log) { - return(FALSE); + recv_report_corrupt_log(ptr, + type, space, page_no); + } + + return(FALSE); } + recv_previous_parsed_rec_type = (ulint)type; + recv_previous_parsed_rec_offset + = recv_sys->recovered_offset + total_len; + recv_previous_parsed_rec_is_multi = 1; + if ((!store_to_hash) && (type != MLOG_MULTI_REC_END)) { /* In debug checking, update a replicate page according to the log record */ @@ -1946,6 +1984,12 @@ loop: old_lsn = recv_sys->recovered_lsn; len = recv_parse_log_rec(ptr, end_ptr, &type, &space, &page_no, &body); + if (recv_sys->found_corrupt_log) { + + recv_report_corrupt_log(ptr, + type, space, page_no); + } + ut_a(len != 0); ut_a(0 == ((ulint)*ptr & MLOG_SINGLE_REC_FLAG)); @@ -2206,11 +2250,14 @@ recv_scan_log_recs( >= RECV_PARSING_BUF_SIZE) { fprintf(stderr, "InnoDB: Error: log parsing buffer overflow. Recovery may have failed!\n"); - finished = TRUE; + + recv_sys->found_corrupt_log = TRUE; + + } else if (!recv_sys->found_corrupt_log) { + more_data = recv_sys_add_to_parsing_buf( + log_block, scanned_lsn); } - more_data = recv_sys_add_to_parsing_buf(log_block, - scanned_lsn); recv_sys->scanned_lsn = scanned_lsn; recv_sys->scanned_checkpoint_no = log_block_get_checkpoint_no(log_block); @@ -2240,7 +2287,7 @@ recv_scan_log_recs( } } - if (more_data) { + if (more_data && !recv_sys->found_corrupt_log) { /* Try to parse more log records */ recv_parse_log_recs(store_to_hash); @@ -2617,6 +2664,17 @@ recv_recovery_from_checkpoint_finish(void) trx_sys_print_mysql_binlog_offset(); } + if (recv_sys->found_corrupt_log) { + + fprintf(stderr, + "InnoDB: WARNING: the log file may have been corrupt and it\n" + "InnoDB: is possible that the log scan or parsing did not proceed\n" + "InnoDB: far enough in recovery. Please run CHECK TABLE\n" + "InnoDB: on your InnoDB tables to check that they are ok!\n" + "InnoDB: It may be safest to recover your InnoDB database from\n" + "InnoDB: a backup!\n"); + } + /* Free the resources of the recovery system */ recv_recovery_on = FALSE; diff --git a/innobase/mtr/mtr0log.c b/innobase/mtr/mtr0log.c index b582afc5710..2cfe81d3261 100644 --- a/innobase/mtr/mtr0log.c +++ b/innobase/mtr/mtr0log.c @@ -14,6 +14,7 @@ Created 12/7/1995 Heikki Tuuri #include "buf0buf.h" #include "dict0boot.h" +#include "log0recv.h" /************************************************************ Catenates n bytes to the mtr log. */ @@ -121,7 +122,7 @@ byte* mlog_parse_nbytes( /*==============*/ /* out: parsed record end, NULL if not a complete - record */ + record or a corrupt record */ ulint type, /* in: log record type: MLOG_1BYTE, ... */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ @@ -141,6 +142,12 @@ mlog_parse_nbytes( offset = mach_read_from_2(ptr); ptr += 2; + if (offset >= UNIV_PAGE_SIZE) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } + if (type == MLOG_8BYTES) { ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval); @@ -163,13 +170,33 @@ mlog_parse_nbytes( return(NULL); } + if (type == MLOG_1BYTE) { + if (val > 0xFF) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } + } else if (type == MLOG_2BYTES) { + if (val > 0xFFFF) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } + } else { + if (type != MLOG_4BYTES) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } + } + if (page) { if (type == MLOG_1BYTE) { mach_write_to_1(page + offset, val); } else if (type == MLOG_2BYTES) { mach_write_to_2(page + offset, val); } else { - ut_ad(type == MLOG_4BYTES); + ut_a(type == MLOG_4BYTES); mach_write_to_4(page + offset, val); } } @@ -338,7 +365,11 @@ mlog_parse_string( offset = mach_read_from_2(ptr); ptr += 2; - ut_a(offset < UNIV_PAGE_SIZE); + if (offset >= UNIV_PAGE_SIZE) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } len = mach_read_from_2(ptr); ptr += 2; diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 4a1bbfa9874..e40de2198c1 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -22,7 +22,7 @@ Created 10/21/1995 Heikki Tuuri #endif -/* This specifies the file permissions InnoDB uses when it craetes files in +/* This specifies the file permissions InnoDB uses when it creates files in Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to my_umask */ diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index dfe28fd40c4..6ce7008dce0 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -13,6 +13,7 @@ Created 10/4/1994 Heikki Tuuri #include "rem0cmp.h" #include "mtr0log.h" +#include "log0recv.h" ulint page_cur_short_succ = 0; @@ -481,6 +482,9 @@ page_cur_insert_rec_write_log( /* Write the mismatch index */ log_ptr += mach_write_compressed(log_ptr, i); + + ut_a(i < UNIV_PAGE_SIZE); + ut_a(extra_size < UNIV_PAGE_SIZE); } /* Write to the log the inserted index record end segment which @@ -533,6 +537,13 @@ page_cur_parse_insert_rec( } offset = mach_read_from_2(ptr); + + if (offset >= UNIV_PAGE_SIZE) { + + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } ptr += 2; } @@ -546,6 +557,12 @@ page_cur_parse_insert_rec( extra_info_yes = end_seg_len & 0x1; end_seg_len = end_seg_len / 2; + + if (end_seg_len >= UNIV_PAGE_SIZE) { + recv_sys->found_corrupt_log = TRUE; + + return(NULL); + } if (extra_info_yes) { /* Read the info bits */ @@ -565,12 +582,16 @@ page_cur_parse_insert_rec( return(NULL); } + ut_a(origin_offset < UNIV_PAGE_SIZE); + ptr = mach_parse_compressed(ptr, end_ptr, &mismatch_index); if (ptr == NULL) { return(NULL); } + + ut_a(mismatch_index < UNIV_PAGE_SIZE); } if (end_ptr < ptr + end_seg_len) { @@ -607,7 +628,6 @@ page_cur_parse_insert_rec( /* Build the inserted record to buf */ ut_a(mismatch_index < UNIV_PAGE_SIZE); - ut_a(end_seg_len < UNIV_PAGE_SIZE); ut_memcpy(buf, rec_get_start(cursor_rec), mismatch_index); ut_memcpy(buf + mismatch_index, ptr, end_seg_len); @@ -1009,6 +1029,8 @@ page_cur_parse_delete_rec( offset = mach_read_from_2(ptr); ptr += 2; + ut_a(offset <= UNIV_PAGE_SIZE); + if (page) { page_cur_position(page + offset, &cursor); |