Loading innobase/btr/btr0btr.c +22 −5 Original line number Diff line number Diff line Loading @@ -573,6 +573,13 @@ btr_page_get_father_for_rec( if (btr_node_ptr_get_child_page_no(node_ptr) != buf_frame_get_page_no(page)) { fprintf(stderr, "InnoDB: Dump of the child page:\n"); buf_page_print(buf_frame_align(page)); fprintf(stderr, "InnoDB: Dump of the parent page:\n"); buf_page_print(buf_frame_align(node_ptr)); fprintf(stderr, "InnoDB: Corruption of an index tree: table %s, index %s,\n" "InnoDB: father ptr page no %lu, child page no %lu\n", (UT_LIST_GET_FIRST(tree->tree_indexes))->table_name, Loading @@ -581,6 +588,12 @@ btr_page_get_father_for_rec( buf_frame_get_page_no(page)); page_rec_print(page_rec_get_next(page_get_infimum_rec(page))); page_rec_print(node_ptr); fprintf(stderr, "InnoDB: You should dump + drop + reimport the table to fix the\n" "InnoDB: corruption. If the crash happens at the database startup, see\n" "InnoDB: section 6.1 of http://www.innodb.com/ibman.html about forcing\n" "InnoDB: recovery. Then dump + drop + reimport.\n"); } ut_a(btr_node_ptr_get_child_page_no(node_ptr) == Loading Loading @@ -780,12 +793,14 @@ btr_free_root( /***************************************************************** Reorganizes an index page. */ static void btr_page_reorganize_low( /*====================*/ ibool low, /* in: TRUE if locks should not be updated, i.e., there cannot exist locks on the page */ ibool recovery,/* in: TRUE if called in recovery: locks should not be updated, i.e., there cannot exist locks on the page, and a hash index should not be dropped: it cannot exist */ page_t* page, /* in: page to be reorganized */ mtr_t* mtr) /* in: mtr */ { Loading @@ -805,7 +820,9 @@ btr_page_reorganize_low( /* Copy the old page to temporary space */ buf_frame_copy(new_page, page); if (!recovery) { btr_search_drop_page_hash_index(page); } /* Recreate the page: note that global data on page (possible segment headers, next page-field, etc.) is preserved intact */ Loading @@ -820,7 +837,7 @@ btr_page_reorganize_low( /* Copy max trx id to recreated page */ page_set_max_trx_id(page, page_get_max_trx_id(new_page)); if (!low) { if (!recovery) { /* Update the record lock bitmaps */ lock_move_reorganize_page(page, new_page); } Loading innobase/btr/btr0cur.c +72 −13 Original line number Diff line number Diff line Loading @@ -36,9 +36,14 @@ Created 10/16/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "lock0lock.h" /* If the following is set to TRUE, this module prints a lot of trace information of individual record operations */ ibool btr_cur_print_record_ops = FALSE; ulint btr_cur_rnd = 0; ulint btr_cur_n_non_sea = 0; ulint btr_cur_n_sea = 0; /* In the optimistic insert, if the insert does not fit, but this much space can be released by page reorganize, then it is reorganized */ Loading Loading @@ -187,11 +192,7 @@ btr_cur_search_to_nth_level( tuple must be set so that it cannot get compared to the node ptr page number field! */ ulint mode, /* in: PAGE_CUR_L, ...; NOTE that if the search is made using a unique prefix of a record, mode should be PAGE_CUR_LE, not PAGE_CUR_GE, as the latter may end up on the previous page relative to the record! Inserts should always be made using Inserts should always be made using PAGE_CUR_LE to search the position! */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with BTR_INSERT and BTR_ESTIMATE; Loading Loading @@ -268,7 +269,7 @@ btr_cur_search_to_nth_level( #ifdef UNIV_SEARCH_PERF_STAT info->n_searches++; #endif if (btr_search_latch.writer != RW_LOCK_NOT_LOCKED if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate && btr_search_guess_on_hash(index, info, tuple, mode, Loading @@ -283,14 +284,14 @@ btr_cur_search_to_nth_level( || mode != PAGE_CUR_LE); ut_ad(cursor->low_match != ULINT_UNDEFINED || mode != PAGE_CUR_LE); btr_cur_n_sea++; return; } #endif #endif #ifdef UNIV_SEARCH_PERF_STAT btr_cur_n_non_sea++; #endif /* If the hash search did not succeed, do binary search down the tree */ Loading Loading @@ -798,13 +799,26 @@ btr_cur_optimistic_insert( ulint type; ulint err; ut_ad(dtuple_check_typed(entry)); *big_rec = NULL; page = btr_cur_get_page(cursor); index = cursor->index; if (!dtuple_check_typed_no_assert(entry)) { fprintf(stderr, "InnoDB: Error in a tuple to insert into table %lu index %lu\n", index->table_name, index->name); } if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to insert to table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); dtuple_print(entry); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); max_size = page_get_max_insert_size_after_reorganize(page, 1); Loading Loading @@ -928,7 +942,7 @@ btr_cur_optimistic_insert( buf_frame_get_page_no(page), max_size, rec_size + PAGE_DIR_SLOT_SIZE, type); */ if (!(type & (DICT_CLUSTERED | DICT_UNIQUE))) { if (!(type & DICT_CLUSTERED)) { /* We have added a record to page: update its free bits */ ibuf_update_free_bits_if_full(cursor->index, page, max_size, rec_size + PAGE_DIR_SLOT_SIZE); Loading Loading @@ -1258,6 +1272,15 @@ btr_cur_update_sec_rec_in_place( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to update table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr); if (err != DB_SUCCESS) { Loading Loading @@ -1312,6 +1335,15 @@ btr_cur_update_in_place( index = cursor->index; trx = thr_get_trx(thr); if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to update table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } /* Do lock checking and undo logging */ err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr, &roll_ptr); Loading Loading @@ -1398,6 +1430,15 @@ btr_cur_optimistic_update( rec = btr_cur_get_rec(cursor); index = cursor->index; if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to update table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); if (!row_upd_changes_field_size(rec, index, update)) { Loading Loading @@ -1973,6 +2014,15 @@ btr_cur_del_mark_set_clust_rec( rec = btr_cur_get_rec(cursor); index = cursor->index; if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to del mark table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } ut_ad(index->type & DICT_CLUSTERED); ut_ad(rec_get_deleted_flag(rec) == FALSE); Loading Loading @@ -2102,6 +2152,15 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to del mark table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), cursor->index->table_name, cursor->index->name); rec_print(rec); } err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, thr); if (err != DB_SUCCESS) { Loading innobase/btr/btr0sea.c +65 −14 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ Created 2/17/1996 Heikki Tuuri #include "page0page.h" #include "page0cur.h" #include "btr0cur.h" #include "btr0pcur.h" #include "btr0btr.h" ulint btr_search_n_succ = 0; Loading Loading @@ -145,6 +146,8 @@ btr_search_info_create( info = mem_heap_alloc(heap, sizeof(btr_search_t)); info->magic_n = BTR_SEARCH_MAGIC_N; info->last_search = NULL; info->n_direction = 0; info->root_guess = NULL; Loading @@ -159,6 +162,12 @@ btr_search_info_create( info->n_patt_succ = 0; info->n_searches = 0; /* Set some sensible values */ info->n_fields = 1; info->n_bytes = 0; info->side = BTR_SEARCH_LEFT_SIDE; return(info); } Loading Loading @@ -197,7 +206,7 @@ btr_search_info_update_hash( /* Test if the search would have succeeded using the recommended hash prefix */ if ((info->n_fields >= n_unique) && (cursor->up_match >= n_unique)) { if (info->n_fields >= n_unique && cursor->up_match >= n_unique) { info->n_hash_potential++; Loading @@ -207,8 +216,8 @@ btr_search_info_update_hash( cmp = ut_pair_cmp(info->n_fields, info->n_bytes, cursor->low_match, cursor->low_bytes); if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp <= 0)) || ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp > 0))) { if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp <= 0) || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp > 0)) { goto set_new_recomm; } Loading @@ -216,8 +225,8 @@ btr_search_info_update_hash( cmp = ut_pair_cmp(info->n_fields, info->n_bytes, cursor->up_match, cursor->up_bytes); if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp > 0)) || ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp <= 0))) { if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0) || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) { goto set_new_recomm; } Loading @@ -233,19 +242,18 @@ btr_search_info_update_hash( info->hash_analysis = 0; if ((cursor->up_match >= n_unique) || (cursor->low_match >= n_unique)) { info->n_fields = n_unique; info->n_bytes = 0; info->side = BTR_SEARCH_LEFT_SIDE; } cmp = ut_pair_cmp(cursor->up_match, cursor->up_bytes, cursor->low_match, cursor->low_bytes); if (cmp == 0) { info->n_hash_potential = 0; /* For extra safety, we set some sensible values here */ info->n_fields = 1; info->n_bytes = 0; info->side = BTR_SEARCH_LEFT_SIDE; } else if (cmp > 0) { info->n_hash_potential = 1; Loading Loading @@ -305,6 +313,9 @@ btr_search_update_block_hash_info( info->last_hash_succ = FALSE; ut_a(block->magic_n == BUF_BLOCK_MAGIC_N); ut_a(info->magic_n == BTR_SEARCH_MAGIC_N); if ((block->n_hash_helps > 0) && (info->n_hash_potential > 0) && (block->n_fields == info->n_fields) Loading Loading @@ -622,6 +633,7 @@ btr_search_guess_on_hash( dulint tree_id; #ifdef notdefined btr_cur_t cursor2; btr_pcur_t pcur; #endif ut_ad(index && info && tuple && cursor && mtr); ut_ad((latch_mode == BTR_SEARCH_LEAF) Loading Loading @@ -754,7 +766,26 @@ btr_search_guess_on_hash( btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, &cursor2, 0, mtr); if (mode == PAGE_CUR_GE && btr_cur_get_rec(&cursor2) == page_get_supremum_rec( buf_frame_align(btr_cur_get_rec(&cursor2)))) { /* If mode is PAGE_CUR_GE, then the binary search in the index tree may actually take us to the supremum of the previous page */ info->last_hash_succ = FALSE; btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode, &pcur, mtr); ut_a(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor)); } else { ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor)); } /* NOTE that it is theoretically possible that the above assertions fail if the page of the cursor gets removed from the buffer pool meanwhile! Thus it might not be a bug. */ info->last_hash_succ = TRUE; #endif Loading Loading @@ -835,6 +866,8 @@ btr_search_drop_page_hash_index( n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; ut_a(n_fields + n_bytes > 0); rw_lock_s_unlock(&btr_search_latch); n_recs = page_get_n_recs(page); Loading @@ -851,6 +884,14 @@ btr_search_drop_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); if (rec != sup) { ut_a(n_fields <= rec_get_n_fields(rec)); if (n_bytes > 0) { ut_a(n_fields < rec_get_n_fields(rec)); } } tree_id = btr_page_get_index_id(page); prev_fold = 0; Loading Loading @@ -980,6 +1021,8 @@ btr_search_build_page_hash_index( return; } ut_a(n_fields + n_bytes > 0); /* Calculate and cache fold values and corresponding records into an array for fast insertion to the hash index */ Loading @@ -995,6 +1038,14 @@ btr_search_build_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); if (rec != sup) { ut_a(n_fields <= rec_get_n_fields(rec)); if (n_bytes > 0) { ut_a(n_fields < rec_get_n_fields(rec)); } } /* FIXME: in a mixed tree, all records may not have enough ordering fields: */ Loading innobase/buf/buf0buf.c +41 −1 Original line number Diff line number Diff line Loading @@ -1125,13 +1125,51 @@ buf_page_get_known_nowait( return(TRUE); } /************************************************************************ Inits a page to the buffer buf_pool, for use in ibbackup --restore. */ void buf_page_init_for_backup_restore( /*=============================*/ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ buf_block_t* block) /* in: block to init */ { /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; block->lock_hash_val = 0; block->lock_mutex = NULL; block->freed_page_clock = 0; block->newest_modification = ut_dulint_zero; block->oldest_modification = ut_dulint_zero; block->accessed = FALSE; block->buf_fix_count = 0; block->io_fix = 0; block->n_hash_helps = 0; block->is_hashed = FALSE; block->n_fields = 1; block->n_bytes = 0; block->side = BTR_SEARCH_LEFT_SIDE; block->file_page_was_freed = FALSE; } /************************************************************************ Inits a page to the buffer buf_pool. */ static void buf_page_init( /*==========*/ /* out: pointer to the block */ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ Loading @@ -1141,6 +1179,8 @@ buf_page_init( ut_ad(block->state == BUF_BLOCK_READY_FOR_USE); /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; Loading innobase/buf/buf0rea.c +29 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,11 @@ buf_read_page_low( block = buf_page_init_for_read(mode, space, offset); if (block != NULL) { if (buf_debug_prints) { printf("Posting read request for page %lu, sync %lu\n", offset, sync); } fil_io(OS_FILE_READ | wake_later, sync, space, offset, 0, UNIV_PAGE_SIZE, (void*)block->frame, (void*)block); Loading Loading @@ -467,6 +472,12 @@ buf_read_ahead_linear( count = 0; /* Since Windows XP seems to schedule the i/o handler thread very eagerly, and consequently it does not wait for the full read batch to be posted, we use special heuristics here */ os_aio_simulated_put_read_threads_to_sleep(); for (i = low; i < high; i++) { /* It is only sensible to do read-ahead in the non-sync aio mode: hence FALSE as the first parameter */ Loading Loading @@ -556,16 +567,34 @@ buf_read_recv_pages( highest page number the last in the array */ ulint n_stored) /* in: number of page numbers in the array */ { ulint count; ulint i; for (i = 0; i < n_stored; i++) { count = 0; os_aio_print_debug = FALSE; while (buf_pool->n_pend_reads >= RECV_POOL_N_FREE_BLOCKS / 2) { os_aio_simulated_wake_handler_threads(); os_thread_sleep(500000); count++; if (count > 100) { fprintf(stderr, "InnoDB: Error: InnoDB has waited for 50 seconds for pending\n" "InnoDB: reads to the buffer pool to be finished.\n" "InnoDB: Number of pending reads %lu\n", buf_pool->n_pend_reads); os_aio_print_debug = TRUE; } } os_aio_print_debug = FALSE; if ((i + 1 == n_stored) && sync) { buf_read_page_low(TRUE, BUF_READ_ANY_PAGE, space, page_nos[i]); Loading Loading
innobase/btr/btr0btr.c +22 −5 Original line number Diff line number Diff line Loading @@ -573,6 +573,13 @@ btr_page_get_father_for_rec( if (btr_node_ptr_get_child_page_no(node_ptr) != buf_frame_get_page_no(page)) { fprintf(stderr, "InnoDB: Dump of the child page:\n"); buf_page_print(buf_frame_align(page)); fprintf(stderr, "InnoDB: Dump of the parent page:\n"); buf_page_print(buf_frame_align(node_ptr)); fprintf(stderr, "InnoDB: Corruption of an index tree: table %s, index %s,\n" "InnoDB: father ptr page no %lu, child page no %lu\n", (UT_LIST_GET_FIRST(tree->tree_indexes))->table_name, Loading @@ -581,6 +588,12 @@ btr_page_get_father_for_rec( buf_frame_get_page_no(page)); page_rec_print(page_rec_get_next(page_get_infimum_rec(page))); page_rec_print(node_ptr); fprintf(stderr, "InnoDB: You should dump + drop + reimport the table to fix the\n" "InnoDB: corruption. If the crash happens at the database startup, see\n" "InnoDB: section 6.1 of http://www.innodb.com/ibman.html about forcing\n" "InnoDB: recovery. Then dump + drop + reimport.\n"); } ut_a(btr_node_ptr_get_child_page_no(node_ptr) == Loading Loading @@ -780,12 +793,14 @@ btr_free_root( /***************************************************************** Reorganizes an index page. */ static void btr_page_reorganize_low( /*====================*/ ibool low, /* in: TRUE if locks should not be updated, i.e., there cannot exist locks on the page */ ibool recovery,/* in: TRUE if called in recovery: locks should not be updated, i.e., there cannot exist locks on the page, and a hash index should not be dropped: it cannot exist */ page_t* page, /* in: page to be reorganized */ mtr_t* mtr) /* in: mtr */ { Loading @@ -805,7 +820,9 @@ btr_page_reorganize_low( /* Copy the old page to temporary space */ buf_frame_copy(new_page, page); if (!recovery) { btr_search_drop_page_hash_index(page); } /* Recreate the page: note that global data on page (possible segment headers, next page-field, etc.) is preserved intact */ Loading @@ -820,7 +837,7 @@ btr_page_reorganize_low( /* Copy max trx id to recreated page */ page_set_max_trx_id(page, page_get_max_trx_id(new_page)); if (!low) { if (!recovery) { /* Update the record lock bitmaps */ lock_move_reorganize_page(page, new_page); } Loading
innobase/btr/btr0cur.c +72 −13 Original line number Diff line number Diff line Loading @@ -36,9 +36,14 @@ Created 10/16/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "lock0lock.h" /* If the following is set to TRUE, this module prints a lot of trace information of individual record operations */ ibool btr_cur_print_record_ops = FALSE; ulint btr_cur_rnd = 0; ulint btr_cur_n_non_sea = 0; ulint btr_cur_n_sea = 0; /* In the optimistic insert, if the insert does not fit, but this much space can be released by page reorganize, then it is reorganized */ Loading Loading @@ -187,11 +192,7 @@ btr_cur_search_to_nth_level( tuple must be set so that it cannot get compared to the node ptr page number field! */ ulint mode, /* in: PAGE_CUR_L, ...; NOTE that if the search is made using a unique prefix of a record, mode should be PAGE_CUR_LE, not PAGE_CUR_GE, as the latter may end up on the previous page relative to the record! Inserts should always be made using Inserts should always be made using PAGE_CUR_LE to search the position! */ ulint latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with BTR_INSERT and BTR_ESTIMATE; Loading Loading @@ -268,7 +269,7 @@ btr_cur_search_to_nth_level( #ifdef UNIV_SEARCH_PERF_STAT info->n_searches++; #endif if (btr_search_latch.writer != RW_LOCK_NOT_LOCKED if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate && btr_search_guess_on_hash(index, info, tuple, mode, Loading @@ -283,14 +284,14 @@ btr_cur_search_to_nth_level( || mode != PAGE_CUR_LE); ut_ad(cursor->low_match != ULINT_UNDEFINED || mode != PAGE_CUR_LE); btr_cur_n_sea++; return; } #endif #endif #ifdef UNIV_SEARCH_PERF_STAT btr_cur_n_non_sea++; #endif /* If the hash search did not succeed, do binary search down the tree */ Loading Loading @@ -798,13 +799,26 @@ btr_cur_optimistic_insert( ulint type; ulint err; ut_ad(dtuple_check_typed(entry)); *big_rec = NULL; page = btr_cur_get_page(cursor); index = cursor->index; if (!dtuple_check_typed_no_assert(entry)) { fprintf(stderr, "InnoDB: Error in a tuple to insert into table %lu index %lu\n", index->table_name, index->name); } if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to insert to table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); dtuple_print(entry); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); max_size = page_get_max_insert_size_after_reorganize(page, 1); Loading Loading @@ -928,7 +942,7 @@ btr_cur_optimistic_insert( buf_frame_get_page_no(page), max_size, rec_size + PAGE_DIR_SLOT_SIZE, type); */ if (!(type & (DICT_CLUSTERED | DICT_UNIQUE))) { if (!(type & DICT_CLUSTERED)) { /* We have added a record to page: update its free bits */ ibuf_update_free_bits_if_full(cursor->index, page, max_size, rec_size + PAGE_DIR_SLOT_SIZE); Loading Loading @@ -1258,6 +1272,15 @@ btr_cur_update_sec_rec_in_place( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to update table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } err = lock_sec_rec_modify_check_and_lock(0, rec, index, thr); if (err != DB_SUCCESS) { Loading Loading @@ -1312,6 +1335,15 @@ btr_cur_update_in_place( index = cursor->index; trx = thr_get_trx(thr); if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to update table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } /* Do lock checking and undo logging */ err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr, &roll_ptr); Loading Loading @@ -1398,6 +1430,15 @@ btr_cur_optimistic_update( rec = btr_cur_get_rec(cursor); index = cursor->index; if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to update table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); if (!row_upd_changes_field_size(rec, index, update)) { Loading Loading @@ -1973,6 +2014,15 @@ btr_cur_del_mark_set_clust_rec( rec = btr_cur_get_rec(cursor); index = cursor->index; if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to del mark table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), index->table_name, index->name); rec_print(rec); } ut_ad(index->type & DICT_CLUSTERED); ut_ad(rec_get_deleted_flag(rec) == FALSE); Loading Loading @@ -2102,6 +2152,15 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); if (btr_cur_print_record_ops && thr) { printf( "Trx with id %lu %lu going to del mark table %s index %s\n", ut_dulint_get_high(thr_get_trx(thr)->id), ut_dulint_get_low(thr_get_trx(thr)->id), cursor->index->table_name, cursor->index->name); rec_print(rec); } err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index, thr); if (err != DB_SUCCESS) { Loading
innobase/btr/btr0sea.c +65 −14 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ Created 2/17/1996 Heikki Tuuri #include "page0page.h" #include "page0cur.h" #include "btr0cur.h" #include "btr0pcur.h" #include "btr0btr.h" ulint btr_search_n_succ = 0; Loading Loading @@ -145,6 +146,8 @@ btr_search_info_create( info = mem_heap_alloc(heap, sizeof(btr_search_t)); info->magic_n = BTR_SEARCH_MAGIC_N; info->last_search = NULL; info->n_direction = 0; info->root_guess = NULL; Loading @@ -159,6 +162,12 @@ btr_search_info_create( info->n_patt_succ = 0; info->n_searches = 0; /* Set some sensible values */ info->n_fields = 1; info->n_bytes = 0; info->side = BTR_SEARCH_LEFT_SIDE; return(info); } Loading Loading @@ -197,7 +206,7 @@ btr_search_info_update_hash( /* Test if the search would have succeeded using the recommended hash prefix */ if ((info->n_fields >= n_unique) && (cursor->up_match >= n_unique)) { if (info->n_fields >= n_unique && cursor->up_match >= n_unique) { info->n_hash_potential++; Loading @@ -207,8 +216,8 @@ btr_search_info_update_hash( cmp = ut_pair_cmp(info->n_fields, info->n_bytes, cursor->low_match, cursor->low_bytes); if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp <= 0)) || ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp > 0))) { if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp <= 0) || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp > 0)) { goto set_new_recomm; } Loading @@ -216,8 +225,8 @@ btr_search_info_update_hash( cmp = ut_pair_cmp(info->n_fields, info->n_bytes, cursor->up_match, cursor->up_bytes); if (((info->side == BTR_SEARCH_LEFT_SIDE) && (cmp > 0)) || ((info->side == BTR_SEARCH_RIGHT_SIDE) && (cmp <= 0))) { if ((info->side == BTR_SEARCH_LEFT_SIDE && cmp > 0) || (info->side == BTR_SEARCH_RIGHT_SIDE && cmp <= 0)) { goto set_new_recomm; } Loading @@ -233,19 +242,18 @@ btr_search_info_update_hash( info->hash_analysis = 0; if ((cursor->up_match >= n_unique) || (cursor->low_match >= n_unique)) { info->n_fields = n_unique; info->n_bytes = 0; info->side = BTR_SEARCH_LEFT_SIDE; } cmp = ut_pair_cmp(cursor->up_match, cursor->up_bytes, cursor->low_match, cursor->low_bytes); if (cmp == 0) { info->n_hash_potential = 0; /* For extra safety, we set some sensible values here */ info->n_fields = 1; info->n_bytes = 0; info->side = BTR_SEARCH_LEFT_SIDE; } else if (cmp > 0) { info->n_hash_potential = 1; Loading Loading @@ -305,6 +313,9 @@ btr_search_update_block_hash_info( info->last_hash_succ = FALSE; ut_a(block->magic_n == BUF_BLOCK_MAGIC_N); ut_a(info->magic_n == BTR_SEARCH_MAGIC_N); if ((block->n_hash_helps > 0) && (info->n_hash_potential > 0) && (block->n_fields == info->n_fields) Loading Loading @@ -622,6 +633,7 @@ btr_search_guess_on_hash( dulint tree_id; #ifdef notdefined btr_cur_t cursor2; btr_pcur_t pcur; #endif ut_ad(index && info && tuple && cursor && mtr); ut_ad((latch_mode == BTR_SEARCH_LEAF) Loading Loading @@ -754,7 +766,26 @@ btr_search_guess_on_hash( btr_cur_search_to_nth_level(index, 0, tuple, mode, latch_mode, &cursor2, 0, mtr); if (mode == PAGE_CUR_GE && btr_cur_get_rec(&cursor2) == page_get_supremum_rec( buf_frame_align(btr_cur_get_rec(&cursor2)))) { /* If mode is PAGE_CUR_GE, then the binary search in the index tree may actually take us to the supremum of the previous page */ info->last_hash_succ = FALSE; btr_pcur_open_on_user_rec(index, tuple, mode, latch_mode, &pcur, mtr); ut_a(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor)); } else { ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor)); } /* NOTE that it is theoretically possible that the above assertions fail if the page of the cursor gets removed from the buffer pool meanwhile! Thus it might not be a bug. */ info->last_hash_succ = TRUE; #endif Loading Loading @@ -835,6 +866,8 @@ btr_search_drop_page_hash_index( n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; ut_a(n_fields + n_bytes > 0); rw_lock_s_unlock(&btr_search_latch); n_recs = page_get_n_recs(page); Loading @@ -851,6 +884,14 @@ btr_search_drop_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); if (rec != sup) { ut_a(n_fields <= rec_get_n_fields(rec)); if (n_bytes > 0) { ut_a(n_fields < rec_get_n_fields(rec)); } } tree_id = btr_page_get_index_id(page); prev_fold = 0; Loading Loading @@ -980,6 +1021,8 @@ btr_search_build_page_hash_index( return; } ut_a(n_fields + n_bytes > 0); /* Calculate and cache fold values and corresponding records into an array for fast insertion to the hash index */ Loading @@ -995,6 +1038,14 @@ btr_search_build_page_hash_index( rec = page_get_infimum_rec(page); rec = page_rec_get_next(rec); if (rec != sup) { ut_a(n_fields <= rec_get_n_fields(rec)); if (n_bytes > 0) { ut_a(n_fields < rec_get_n_fields(rec)); } } /* FIXME: in a mixed tree, all records may not have enough ordering fields: */ Loading
innobase/buf/buf0buf.c +41 −1 Original line number Diff line number Diff line Loading @@ -1125,13 +1125,51 @@ buf_page_get_known_nowait( return(TRUE); } /************************************************************************ Inits a page to the buffer buf_pool, for use in ibbackup --restore. */ void buf_page_init_for_backup_restore( /*=============================*/ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ buf_block_t* block) /* in: block to init */ { /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; block->lock_hash_val = 0; block->lock_mutex = NULL; block->freed_page_clock = 0; block->newest_modification = ut_dulint_zero; block->oldest_modification = ut_dulint_zero; block->accessed = FALSE; block->buf_fix_count = 0; block->io_fix = 0; block->n_hash_helps = 0; block->is_hashed = FALSE; block->n_fields = 1; block->n_bytes = 0; block->side = BTR_SEARCH_LEFT_SIDE; block->file_page_was_freed = FALSE; } /************************************************************************ Inits a page to the buffer buf_pool. */ static void buf_page_init( /*==========*/ /* out: pointer to the block */ ulint space, /* in: space id */ ulint offset, /* in: offset of the page within space in units of a page */ Loading @@ -1141,6 +1179,8 @@ buf_page_init( ut_ad(block->state == BUF_BLOCK_READY_FOR_USE); /* Set the state of the block */ block->magic_n = BUF_BLOCK_MAGIC_N; block->state = BUF_BLOCK_FILE_PAGE; block->space = space; block->offset = offset; Loading
innobase/buf/buf0rea.c +29 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,11 @@ buf_read_page_low( block = buf_page_init_for_read(mode, space, offset); if (block != NULL) { if (buf_debug_prints) { printf("Posting read request for page %lu, sync %lu\n", offset, sync); } fil_io(OS_FILE_READ | wake_later, sync, space, offset, 0, UNIV_PAGE_SIZE, (void*)block->frame, (void*)block); Loading Loading @@ -467,6 +472,12 @@ buf_read_ahead_linear( count = 0; /* Since Windows XP seems to schedule the i/o handler thread very eagerly, and consequently it does not wait for the full read batch to be posted, we use special heuristics here */ os_aio_simulated_put_read_threads_to_sleep(); for (i = low; i < high; i++) { /* It is only sensible to do read-ahead in the non-sync aio mode: hence FALSE as the first parameter */ Loading Loading @@ -556,16 +567,34 @@ buf_read_recv_pages( highest page number the last in the array */ ulint n_stored) /* in: number of page numbers in the array */ { ulint count; ulint i; for (i = 0; i < n_stored; i++) { count = 0; os_aio_print_debug = FALSE; while (buf_pool->n_pend_reads >= RECV_POOL_N_FREE_BLOCKS / 2) { os_aio_simulated_wake_handler_threads(); os_thread_sleep(500000); count++; if (count > 100) { fprintf(stderr, "InnoDB: Error: InnoDB has waited for 50 seconds for pending\n" "InnoDB: reads to the buffer pool to be finished.\n" "InnoDB: Number of pending reads %lu\n", buf_pool->n_pend_reads); os_aio_print_debug = TRUE; } } os_aio_print_debug = FALSE; if ((i + 1 == n_stored) && sync) { buf_read_page_low(TRUE, BUF_READ_ANY_PAGE, space, page_nos[i]); Loading