Loading innobase/btr/btr0btr.c +4 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,7 @@ btr_page_create( ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); page_create(page, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; btr_page_set_index_id(page, tree->id, mtr); } Loading Loading @@ -713,6 +714,7 @@ btr_create( /* Create a new index page on the the allocated segment page */ page = page_create(frame, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; /* Set the index id of the page */ btr_page_set_index_id(page, index_id, mtr); Loading Loading @@ -847,6 +849,7 @@ btr_page_reorganize_low( segment headers, next page-field, etc.) is preserved intact */ page_create(page, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; /* Copy the records from the temporary space to the recreated page; do not copy the lock bits yet */ Loading Loading @@ -919,6 +922,7 @@ btr_page_empty( segment headers, next page-field, etc.) is preserved intact */ page_create(page, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; } /***************************************************************** Loading innobase/btr/btr0cur.c +35 −8 Original line number Diff line number Diff line Loading @@ -121,16 +121,19 @@ btr_cur_latch_leaves( { ulint left_page_no; ulint right_page_no; page_t* get_page; ut_ad(tree && page && mtr); if (latch_mode == BTR_SEARCH_LEAF) { btr_page_get(space, page_no, RW_S_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else if (latch_mode == BTR_MODIFY_LEAF) { btr_page_get(space, page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else if (latch_mode == BTR_MODIFY_TREE) { Loading @@ -138,15 +141,22 @@ btr_cur_latch_leaves( left_page_no = btr_page_get_prev(page, mtr); if (left_page_no != FIL_NULL) { btr_page_get(space, left_page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, left_page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } btr_page_get(space, page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; right_page_no = btr_page_get_next(page, mtr); if (right_page_no != FIL_NULL) { btr_page_get(space, right_page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, right_page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } } else if (latch_mode == BTR_SEARCH_PREV) { Loading @@ -157,9 +167,12 @@ btr_cur_latch_leaves( if (left_page_no != FIL_NULL) { cursor->left_page = btr_page_get(space, left_page_no, RW_S_LATCH, mtr); buf_block_align( cursor->left_page)->check_index_page_at_flush = TRUE; } btr_page_get(space, page_no, RW_S_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else if (latch_mode == BTR_MODIFY_PREV) { Loading @@ -169,9 +182,12 @@ btr_cur_latch_leaves( if (left_page_no != FIL_NULL) { cursor->left_page = btr_page_get(space, left_page_no, RW_X_LATCH, mtr); buf_block_align( cursor->left_page)->check_index_page_at_flush = TRUE; } btr_page_get(space, page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else { ut_error; } Loading Loading @@ -274,6 +290,7 @@ btr_cur_search_to_nth_level( if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate && mode != PAGE_CUR_LE_OR_EXTENDS && btr_search_guess_on_hash(index, info, tuple, mode, latch_mode, cursor, has_search_latch, mtr)) { Loading Loading @@ -334,12 +351,18 @@ btr_cur_search_to_nth_level( rw_latch = RW_NO_LATCH; buf_mode = BUF_GET; /* We use these modified search modes on non-leaf levels of the B-tree. These let us end up in the right B-tree leaf. In that leaf we use the original search mode. */ if (mode == PAGE_CUR_GE) { page_mode = PAGE_CUR_L; } else if (mode == PAGE_CUR_G) { page_mode = PAGE_CUR_LE; } else if (mode == PAGE_CUR_LE) { page_mode = PAGE_CUR_LE; } else if (mode == PAGE_CUR_LE_OR_EXTENDS) { page_mode = PAGE_CUR_LE_OR_EXTENDS; } else { ut_ad(mode == PAGE_CUR_L); page_mode = PAGE_CUR_L; Loading Loading @@ -391,6 +414,8 @@ btr_cur_search_to_nth_level( goto retry_page_get; } buf_block_align(page)->check_index_page_at_flush = TRUE; #ifdef UNIV_SYNC_DEBUG if (rw_latch != RW_NO_LATCH) { buf_page_dbg_add_level(page, SYNC_TREE_NODE); Loading Loading @@ -543,6 +568,8 @@ btr_cur_open_at_index_side( ut_ad(0 == ut_dulint_cmp(tree->id, btr_page_get_index_id(page))); buf_block_align(page)->check_index_page_at_flush = TRUE; if (height == ULINT_UNDEFINED) { /* We are in the root node */ Loading innobase/btr/btr0pcur.c +1 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ btr_pcur_move_to_next_page( ut_ad(next_page_no != FIL_NULL); next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr); buf_block_align(next_page)->check_index_page_at_flush = TRUE; btr_leaf_page_release(page, cursor->latch_mode, mtr); Loading innobase/buf/buf0buf.c +32 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,11 @@ buf_page_print( index->table_name, index->name); } } else if (fil_page_get_type(read_buf) == FIL_PAGE_INODE) { fprintf(stderr, "InnoDB: Page may be an 'inode' page\n"); } else if (fil_page_get_type(read_buf) == FIL_PAGE_IBUF_FREE_LIST) { fprintf(stderr, "InnoDB: Page may be an insert buffer free list page\n"); } } Loading @@ -351,6 +356,8 @@ buf_block_init( block->file_page_was_freed = FALSE; block->check_index_page_at_flush = FALSE; rw_lock_create(&(block->lock)); ut_ad(rw_lock_validate(&(block->lock))); Loading Loading @@ -616,6 +623,29 @@ buf_page_peek_block( return(block); } /************************************************************************ Resets the check_index_page_at_flush field of a page if found in the buffer pool. */ void buf_reset_check_index_page_at_flush( /*================================*/ ulint space, /* in: space id */ ulint offset) /* in: page number */ { buf_block_t* block; mutex_enter_fast(&(buf_pool->mutex)); block = buf_page_hash_get(space, offset); if (block) { block->check_index_page_at_flush = FALSE; } mutex_exit(&(buf_pool->mutex)); } /************************************************************************ Returns the current state of is_hashed of a page. FALSE if the page is not in the pool. NOTE that this operation does not fix the page in the Loading Loading @@ -1185,6 +1215,8 @@ buf_page_init( block->space = space; block->offset = offset; block->check_index_page_at_flush = FALSE; block->lock_hash_val = lock_rec_hash(space, offset); block->lock_mutex = NULL; Loading innobase/buf/buf0flu.c +19 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ Created 11/11/1995 Heikki Tuuri #include "ut0byte.h" #include "ut0lst.h" #include "page0page.h" #include "fil0fil.h" #include "buf0buf.h" #include "buf0lru.h" Loading Loading @@ -225,6 +226,24 @@ buf_flush_buffered_writes(void) return; } for (i = 0; i < trx_doublewrite->first_free; i++) { block = trx_doublewrite->buf_block_arr[i]; if (block->check_index_page_at_flush && !page_simple_validate(block->frame)) { buf_page_print(block->frame); ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Apparent corruption of an index page\n" "InnoDB: to be written to data file. We intentionally crash server\n" "InnoDB: to prevent corrupt data from ending up in data\n" "InnoDB: files.\n"); ut_a(0); } } if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; } else { Loading Loading
innobase/btr/btr0btr.c +4 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,7 @@ btr_page_create( ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); page_create(page, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; btr_page_set_index_id(page, tree->id, mtr); } Loading Loading @@ -713,6 +714,7 @@ btr_create( /* Create a new index page on the the allocated segment page */ page = page_create(frame, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; /* Set the index id of the page */ btr_page_set_index_id(page, index_id, mtr); Loading Loading @@ -847,6 +849,7 @@ btr_page_reorganize_low( segment headers, next page-field, etc.) is preserved intact */ page_create(page, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; /* Copy the records from the temporary space to the recreated page; do not copy the lock bits yet */ Loading Loading @@ -919,6 +922,7 @@ btr_page_empty( segment headers, next page-field, etc.) is preserved intact */ page_create(page, mtr); buf_block_align(page)->check_index_page_at_flush = TRUE; } /***************************************************************** Loading
innobase/btr/btr0cur.c +35 −8 Original line number Diff line number Diff line Loading @@ -121,16 +121,19 @@ btr_cur_latch_leaves( { ulint left_page_no; ulint right_page_no; page_t* get_page; ut_ad(tree && page && mtr); if (latch_mode == BTR_SEARCH_LEAF) { btr_page_get(space, page_no, RW_S_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else if (latch_mode == BTR_MODIFY_LEAF) { btr_page_get(space, page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else if (latch_mode == BTR_MODIFY_TREE) { Loading @@ -138,15 +141,22 @@ btr_cur_latch_leaves( left_page_no = btr_page_get_prev(page, mtr); if (left_page_no != FIL_NULL) { btr_page_get(space, left_page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, left_page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } btr_page_get(space, page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; right_page_no = btr_page_get_next(page, mtr); if (right_page_no != FIL_NULL) { btr_page_get(space, right_page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, right_page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } } else if (latch_mode == BTR_SEARCH_PREV) { Loading @@ -157,9 +167,12 @@ btr_cur_latch_leaves( if (left_page_no != FIL_NULL) { cursor->left_page = btr_page_get(space, left_page_no, RW_S_LATCH, mtr); buf_block_align( cursor->left_page)->check_index_page_at_flush = TRUE; } btr_page_get(space, page_no, RW_S_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_S_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else if (latch_mode == BTR_MODIFY_PREV) { Loading @@ -169,9 +182,12 @@ btr_cur_latch_leaves( if (left_page_no != FIL_NULL) { cursor->left_page = btr_page_get(space, left_page_no, RW_X_LATCH, mtr); buf_block_align( cursor->left_page)->check_index_page_at_flush = TRUE; } btr_page_get(space, page_no, RW_X_LATCH, mtr); get_page = btr_page_get(space, page_no, RW_X_LATCH, mtr); buf_block_align(get_page)->check_index_page_at_flush = TRUE; } else { ut_error; } Loading Loading @@ -274,6 +290,7 @@ btr_cur_search_to_nth_level( if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate && mode != PAGE_CUR_LE_OR_EXTENDS && btr_search_guess_on_hash(index, info, tuple, mode, latch_mode, cursor, has_search_latch, mtr)) { Loading Loading @@ -334,12 +351,18 @@ btr_cur_search_to_nth_level( rw_latch = RW_NO_LATCH; buf_mode = BUF_GET; /* We use these modified search modes on non-leaf levels of the B-tree. These let us end up in the right B-tree leaf. In that leaf we use the original search mode. */ if (mode == PAGE_CUR_GE) { page_mode = PAGE_CUR_L; } else if (mode == PAGE_CUR_G) { page_mode = PAGE_CUR_LE; } else if (mode == PAGE_CUR_LE) { page_mode = PAGE_CUR_LE; } else if (mode == PAGE_CUR_LE_OR_EXTENDS) { page_mode = PAGE_CUR_LE_OR_EXTENDS; } else { ut_ad(mode == PAGE_CUR_L); page_mode = PAGE_CUR_L; Loading Loading @@ -391,6 +414,8 @@ btr_cur_search_to_nth_level( goto retry_page_get; } buf_block_align(page)->check_index_page_at_flush = TRUE; #ifdef UNIV_SYNC_DEBUG if (rw_latch != RW_NO_LATCH) { buf_page_dbg_add_level(page, SYNC_TREE_NODE); Loading Loading @@ -543,6 +568,8 @@ btr_cur_open_at_index_side( ut_ad(0 == ut_dulint_cmp(tree->id, btr_page_get_index_id(page))); buf_block_align(page)->check_index_page_at_flush = TRUE; if (height == ULINT_UNDEFINED) { /* We are in the root node */ Loading
innobase/btr/btr0pcur.c +1 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ btr_pcur_move_to_next_page( ut_ad(next_page_no != FIL_NULL); next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr); buf_block_align(next_page)->check_index_page_at_flush = TRUE; btr_leaf_page_release(page, cursor->latch_mode, mtr); Loading
innobase/buf/buf0buf.c +32 −0 Original line number Diff line number Diff line Loading @@ -331,6 +331,11 @@ buf_page_print( index->table_name, index->name); } } else if (fil_page_get_type(read_buf) == FIL_PAGE_INODE) { fprintf(stderr, "InnoDB: Page may be an 'inode' page\n"); } else if (fil_page_get_type(read_buf) == FIL_PAGE_IBUF_FREE_LIST) { fprintf(stderr, "InnoDB: Page may be an insert buffer free list page\n"); } } Loading @@ -351,6 +356,8 @@ buf_block_init( block->file_page_was_freed = FALSE; block->check_index_page_at_flush = FALSE; rw_lock_create(&(block->lock)); ut_ad(rw_lock_validate(&(block->lock))); Loading Loading @@ -616,6 +623,29 @@ buf_page_peek_block( return(block); } /************************************************************************ Resets the check_index_page_at_flush field of a page if found in the buffer pool. */ void buf_reset_check_index_page_at_flush( /*================================*/ ulint space, /* in: space id */ ulint offset) /* in: page number */ { buf_block_t* block; mutex_enter_fast(&(buf_pool->mutex)); block = buf_page_hash_get(space, offset); if (block) { block->check_index_page_at_flush = FALSE; } mutex_exit(&(buf_pool->mutex)); } /************************************************************************ Returns the current state of is_hashed of a page. FALSE if the page is not in the pool. NOTE that this operation does not fix the page in the Loading Loading @@ -1185,6 +1215,8 @@ buf_page_init( block->space = space; block->offset = offset; block->check_index_page_at_flush = FALSE; block->lock_hash_val = lock_rec_hash(space, offset); block->lock_mutex = NULL; Loading
innobase/buf/buf0flu.c +19 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ Created 11/11/1995 Heikki Tuuri #include "ut0byte.h" #include "ut0lst.h" #include "page0page.h" #include "fil0fil.h" #include "buf0buf.h" #include "buf0lru.h" Loading Loading @@ -225,6 +226,24 @@ buf_flush_buffered_writes(void) return; } for (i = 0; i < trx_doublewrite->first_free; i++) { block = trx_doublewrite->buf_block_arr[i]; if (block->check_index_page_at_flush && !page_simple_validate(block->frame)) { buf_page_print(block->frame); ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Apparent corruption of an index page\n" "InnoDB: to be written to data file. We intentionally crash server\n" "InnoDB: to prevent corrupt data from ending up in data\n" "InnoDB: files.\n"); ut_a(0); } } if (trx_doublewrite->first_free > TRX_SYS_DOUBLEWRITE_BLOCK_SIZE) { len = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; } else { Loading