#include "univ.i"#include "dict0mem.h"#include "dict0dict.h"#include "mtr0mtr.h"#include "que0types.h"#include "ibuf0types.h"#include "fsp0fsp.h"Include dependency graph for ibuf0ibuf.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
| #define IBUF_HEADER PAGE_DATA |
Definition at line 302 of file ibuf0ibuf.h.
Referenced by btr_create(), ibuf_add_free_page(), ibuf_data_init_for_space(), and ibuf_remove_free_page().
| #define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO |
| #define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO |
Definition at line 298 of file ibuf0ibuf.h.
Referenced by btr_create(), ibuf_fixed_addr_page(), and ibuf_get_merge_page_nos().
| #define IBUF_TREE_SEG_HEADER 0 |
Definition at line 303 of file ibuf0ibuf.h.
Referenced by btr_create(), ibuf_add_free_page(), ibuf_data_init_for_space(), and ibuf_remove_free_page().
| UNIV_INLINE ibool ibuf_bitmap_page | ( | ulint | page_no | ) |
Referenced by buf_page_init_for_read(), buf_read_ahead_linear(), buf_read_ahead_random(), buf_read_page_low(), fil_io(), and ibuf_fixed_addr_page().
Here is the caller graph for this function:

Definition at line 566 of file ibuf0ibuf.c.
References FIL_PAGE_IBUF_BITMAP, fil_page_set_type(), IBUF_BITMAP, IBUF_BITS_PER_PAGE, memset, MLOG_IBUF_BITMAP_INIT, mlog_write_initial_log_record(), and XDES_DESCRIBED_PER_PAGE.
Referenced by fsp_fill_free_list(), and ibuf_parse_bitmap_init().
00568 : bitmap page */ 00569 mtr_t* mtr) /* in: mtr */ 00570 { 00571 ulint bit_offset; 00572 ulint byte_offset; 00573 00574 /* Write all zeros to the bitmap */ 00575 00576 bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE; 00577 00578 byte_offset = bit_offset / 8 + 1; /* better: (bit_offset + 7) / 8 */ 00579 00580 fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP); 00581 00582 memset(page + IBUF_BITMAP, 0, byte_offset); 00583 00584 /* The remaining area (up to the page trailer) is uninitialized. */ 00585 00586 mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr); 00587 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint ibuf_contract | ( | ibool | sync | ) |
Definition at line 2181 of file ibuf0ibuf.c.
References ibuf_contract_ext().
Referenced by ibuf_contract_after_insert(), and ibuf_insert_low().
02183 : a lower limit for the combined size in bytes 02184 of entries which will be merged from ibuf trees to the 02185 pages read, 0 if ibuf is empty */ 02186 ibool sync) /* in: TRUE if the caller wants to wait for the 02187 issued read with the highest tablespace address 02188 to complete */ 02189 { 02190 ulint n_pages; 02191 02192 return(ibuf_contract_ext(&n_pages, sync)); 02193 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2199 of file ibuf0ibuf.c.
References ibuf_contract_ext().
Referenced by srv_master_thread().
02201 : a lower limit for the combined size in bytes 02202 of entries which will be merged from ibuf trees to the 02203 pages read, 0 if ibuf is empty */ 02204 ibool sync, /* in: TRUE if the caller wants to wait for the 02205 issued read with the highest tablespace address 02206 to complete */ 02207 ulint n_pages)/* in: try to read at least this many pages to 02208 the buffer pool and merge the ibuf contents to 02209 them */ 02210 { 02211 ulint sum_bytes = 0; 02212 ulint sum_pages = 0; 02213 ulint n_bytes; 02214 ulint n_pag2; 02215 02216 while (sum_pages < n_pages) { 02217 n_bytes = ibuf_contract_ext(&n_pag2, sync); 02218 02219 if (n_bytes == 0) { 02220 return(sum_bytes); 02221 } 02222 02223 sum_bytes += n_bytes; 02224 sum_pages += n_pag2; 02225 } 02226 02227 return(sum_bytes); 02228 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibuf_data_t* ibuf_data_init_for_space | ( | ulint | space | ) |
Definition at line 458 of file ibuf0ibuf.c.
References buf, buf_page_get, data, DATA_BINARY, DICT_CLUSTERED, DICT_IBUF, DICT_IBUF_ID_MIN, dict_index_add_to_cache(), dict_mem_index_add_field(), dict_mem_index_create(), dict_mem_table_add_col(), dict_mem_table_create(), dict_table_add_to_cache(), dict_table_get_first_index(), DICT_UNIVERSAL, fil_space_get_latch(), fseg_n_reserved_pages(), FSP_IBUF_TREE_ROOT_PAGE_NO, ibuf, ibuf_data_sizes_update(), ibuf_enter(), ibuf_exit(), IBUF_HEADER, ibuf_header_page_get(), ibuf_mutex, IBUF_TREE_SEG_HEADER, dict_table_struct::id, index(), mem_alloc, mtr_commit(), mtr_start(), mtr_x_lock, mutex_enter, mutex_exit(), NULL, page_t, RW_X_LATCH, SYNC_TREE_NODE, ut_a, ut_ad, ut_dulint_add(), and UT_LIST_ADD_LAST.
Referenced by fil_ibuf_init_at_db_start().
00460 : ibuf data struct, linked to the list 00461 in ibuf control structure */ 00462 ulint space) /* in: space id */ 00463 { 00464 ibuf_data_t* data; 00465 page_t* root; 00466 page_t* header_page; 00467 mtr_t mtr; 00468 char buf[50]; 00469 dict_table_t* table; 00470 dict_index_t* index; 00471 ulint n_used; 00472 00473 ut_a(space == 0); 00474 00475 #ifdef UNIV_LOG_DEBUG 00476 if (space % 2 == 1) { 00477 00478 fputs("No ibuf op in replicate space\n", stderr); 00479 00480 return(NULL); 00481 } 00482 #endif 00483 data = mem_alloc(sizeof(ibuf_data_t)); 00484 00485 data->space = space; 00486 00487 mtr_start(&mtr); 00488 00489 mutex_enter(&ibuf_mutex); 00490 00491 mtr_x_lock(fil_space_get_latch(space), &mtr); 00492 00493 header_page = ibuf_header_page_get(space, &mtr); 00494 00495 fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER, 00496 &n_used, &mtr); 00497 ibuf_enter(); 00498 00499 ut_ad(n_used >= 2); 00500 00501 data->seg_size = n_used; 00502 00503 root = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH, 00504 &mtr); 00505 #ifdef UNIV_SYNC_DEBUG 00506 buf_page_dbg_add_level(root, SYNC_TREE_NODE); 00507 #endif /* UNIV_SYNC_DEBUG */ 00508 00509 data->size = 0; 00510 data->n_inserts = 0; 00511 data->n_merges = 0; 00512 data->n_merged_recs = 0; 00513 00514 ibuf_data_sizes_update(data, root, &mtr); 00515 /* 00516 if (!data->empty) { 00517 fprintf(stderr, 00518 "InnoDB: index entries found in the insert buffer\n"); 00519 } else { 00520 fprintf(stderr, 00521 "InnoDB: insert buffer empty\n"); 00522 } 00523 */ 00524 mutex_exit(&ibuf_mutex); 00525 00526 mtr_commit(&mtr); 00527 00528 ibuf_exit(); 00529 00530 sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space); 00531 /* use old-style record format for the insert buffer */ 00532 table = dict_mem_table_create(buf, space, 2, 0); 00533 00534 dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0); 00535 dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0); 00536 00537 table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); 00538 00539 dict_table_add_to_cache(table); 00540 00541 index = dict_mem_index_create(buf, "CLUST_IND", space, 00542 DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2); 00543 00544 dict_mem_index_add_field(index, "PAGE_NO", 0); 00545 dict_mem_index_add_field(index, "TYPES", 0); 00546 00547 index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space); 00548 00549 dict_index_add_to_cache(table, index, FSP_IBUF_TREE_ROOT_PAGE_NO); 00550 00551 data->index = dict_table_get_first_index(table); 00552 00553 mutex_enter(&ibuf_mutex); 00554 00555 UT_LIST_ADD_LAST(data_list, ibuf->data_list, data); 00556 00557 mutex_exit(&ibuf_mutex); 00558 00559 return(data); 00560 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void ibuf_delete_for_discarded_space | ( | ulint | space | ) |
Definition at line 3321 of file ibuf0ibuf.c.
References BTR_MODIFY_LEAF, btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_after_last_in_tree(), btr_pcur_is_after_last_on_page(), btr_pcur_is_on_user_rec(), btr_pcur_open_on_user_rec(), fil_space_get_ibuf_data(), ibuf_delete_rec(), ibuf_enter(), ibuf_exit(), ibuf_mutex, ibuf_new_search_tuple_build(), ibuf_rec_get_page_no(), ibuf_rec_get_space(), mem_heap_create, mem_heap_free, mtr_commit(), mtr_start(), mutex_enter, mutex_exit(), PAGE_CUR_GE, and ut_ad.
Referenced by fil_discard_tablespace(), and row_import_tablespace_for_mysql().
03323 : space id */ 03324 { 03325 mem_heap_t* heap; 03326 btr_pcur_t pcur; 03327 dtuple_t* search_tuple; 03328 rec_t* ibuf_rec; 03329 ulint page_no; 03330 ibool closed; 03331 ibuf_data_t* ibuf_data; 03332 ulint n_inserts; 03333 mtr_t mtr; 03334 03335 /* Currently the insert buffer of space 0 takes care of inserts to all 03336 tablespaces */ 03337 03338 ibuf_data = fil_space_get_ibuf_data(0); 03339 03340 heap = mem_heap_create(512); 03341 03342 /* Use page number 0 to build the search tuple so that we get the 03343 cursor positioned at the first entry for this space id */ 03344 03345 search_tuple = ibuf_new_search_tuple_build(space, 0, heap); 03346 03347 n_inserts = 0; 03348 loop: 03349 ibuf_enter(); 03350 03351 mtr_start(&mtr); 03352 03353 /* Position pcur in the insert buffer at the first entry for the 03354 space */ 03355 btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE, 03356 BTR_MODIFY_LEAF, &pcur, &mtr); 03357 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 03358 ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); 03359 03360 goto leave_loop; 03361 } 03362 03363 for (;;) { 03364 ut_ad(btr_pcur_is_on_user_rec(&pcur, &mtr)); 03365 03366 ibuf_rec = btr_pcur_get_rec(&pcur); 03367 03368 /* Check if the entry is for this space */ 03369 if (ibuf_rec_get_space(ibuf_rec) != space) { 03370 03371 goto leave_loop; 03372 } 03373 03374 page_no = ibuf_rec_get_page_no(ibuf_rec); 03375 03376 n_inserts++; 03377 03378 /* Delete the record from ibuf */ 03379 closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple, 03380 &mtr); 03381 if (closed) { 03382 /* Deletion was pessimistic and mtr was committed: 03383 we start from the beginning again */ 03384 03385 ibuf_exit(); 03386 03387 goto loop; 03388 } 03389 03390 if (btr_pcur_is_after_last_on_page(&pcur, &mtr)) { 03391 mtr_commit(&mtr); 03392 btr_pcur_close(&pcur); 03393 03394 ibuf_exit(); 03395 03396 goto loop; 03397 } 03398 } 03399 03400 leave_loop: 03401 mtr_commit(&mtr); 03402 btr_pcur_close(&pcur); 03403 03404 /* Protect our statistics keeping from race conditions */ 03405 mutex_enter(&ibuf_mutex); 03406 03407 ibuf_data->n_merges++; 03408 ibuf_data->n_merged_recs += n_inserts; 03409 03410 mutex_exit(&ibuf_mutex); 03411 /* 03412 fprintf(stderr, 03413 "InnoDB: Discarded %lu ibuf entries for space %lu\n", 03414 (ulong) n_inserts, (ulong) space); 03415 */ 03416 ibuf_exit(); 03417 03418 mem_heap_free(heap); 03419 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void ibuf_free_excess_pages | ( | ulint | space | ) |
Definition at line 1829 of file ibuf0ibuf.c.
References fil_space_get_ibuf_data(), fil_space_get_latch(), ibuf_data_too_much_free(), ibuf_inside(), ibuf_mutex, ibuf_remove_free_page(), mutex_enter, mutex_exit(), NULL, RW_LOCK_EX, rw_lock_get_x_lock_count(), and ut_ad.
Referenced by fseg_alloc_free_page_general(), and fseg_create_general().
01831 : space id */ 01832 { 01833 ibuf_data_t* ibuf_data; 01834 ulint i; 01835 01836 if (space != 0) { 01837 fprintf(stderr, 01838 "InnoDB: Error: calling ibuf_free_excess_pages for space %lu\n", (ulong) space); 01839 return; 01840 } 01841 01842 #ifdef UNIV_SYNC_DEBUG 01843 ut_ad(rw_lock_own(fil_space_get_latch(space), RW_LOCK_EX)); 01844 #endif /* UNIV_SYNC_DEBUG */ 01845 ut_ad(rw_lock_get_x_lock_count(fil_space_get_latch(space)) == 1); 01846 ut_ad(!ibuf_inside()); 01847 01848 /* NOTE: We require that the thread did not own the latch before, 01849 because then we know that we can obey the correct latching order 01850 for ibuf latches */ 01851 01852 ibuf_data = fil_space_get_ibuf_data(space); 01853 01854 if (ibuf_data == NULL) { 01855 /* Not yet initialized */ 01856 01857 #ifdef UNIV_DEBUG 01858 /*fprintf(stderr, 01859 "Ibuf for space %lu not yet initialized\n", space); */ 01860 #endif 01861 01862 return; 01863 } 01864 01865 /* Free at most a few pages at a time, so that we do not delay the 01866 requested service too much */ 01867 01868 for (i = 0; i < 4; i++) { 01869 01870 mutex_enter(&ibuf_mutex); 01871 01872 if (!ibuf_data_too_much_free(ibuf_data)) { 01873 01874 mutex_exit(&ibuf_mutex); 01875 01876 return; 01877 } 01878 01879 mutex_exit(&ibuf_mutex); 01880 01881 ibuf_remove_free_page(space, ibuf_data); 01882 } 01883 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void ibuf_init_at_db_start | ( | void | ) |
Definition at line 365 of file ibuf0ibuf.c.
References buf_pool_get_curr_size(), fil_ibuf_init_at_db_start(), ibuf, ibuf_bitmap_mutex, ibuf_mutex, ibuf_pessimistic_insert_mutex, IBUF_POOL_SIZE_PER_MAX_SIZE, mem_alloc, mutex_create, SYNC_IBUF_BITMAP_MUTEX, SYNC_IBUF_MUTEX, SYNC_IBUF_PESS_INSERT_MUTEX, TRUE, UNIV_PAGE_SIZE, and UT_LIST_INIT.
Referenced by dict_boot().
00367 { 00368 ibuf = mem_alloc(sizeof(ibuf_t)); 00369 00370 /* Note that also a pessimistic delete can sometimes make a B-tree 00371 grow in size, as the references on the upper levels of the tree can 00372 change */ 00373 00374 ibuf->max_size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE 00375 / IBUF_POOL_SIZE_PER_MAX_SIZE; 00376 ibuf->meter = IBUF_THRESHOLD + 1; 00377 00378 UT_LIST_INIT(ibuf->data_list); 00379 00380 ibuf->size = 0; 00381 00382 #ifdef UNIV_IBUF_DEBUG 00383 { 00384 ulint i, j; 00385 00386 for (i = 0; i < IBUF_COUNT_N_SPACES; i++) { 00387 00388 ibuf_counts[i] = mem_alloc(sizeof(ulint) 00389 * IBUF_COUNT_N_PAGES); 00390 for (j = 0; j < IBUF_COUNT_N_PAGES; j++) { 00391 ibuf_count_set(i, j, 0); 00392 } 00393 } 00394 00395 ibuf_counts_inited = TRUE; 00396 } 00397 #endif 00398 mutex_create(&ibuf_pessimistic_insert_mutex, 00399 SYNC_IBUF_PESS_INSERT_MUTEX); 00400 00401 mutex_create(&ibuf_mutex, SYNC_IBUF_MUTEX); 00402 00403 mutex_create(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX); 00404 00405 fil_ibuf_init_at_db_start(); 00406 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool ibuf_insert | ( | dtuple_t * | entry, | |
| dict_index_t * | index, | |||
| ulint | space, | |||
| ulint | page_no, | |||
| que_thr_t * | thr | |||
| ) |
Definition at line 2762 of file ibuf0ibuf.c.
References BTR_MODIFY_PREV, BTR_MODIFY_TREE, DB_FAIL, DB_STRONG_FAIL, DB_SUCCESS, DICT_CLUSTERED, dict_table_is_comp(), dtuple_check_typed(), err, FALSE, ibuf_insert_low(), index(), page_get_free_space_of_empty(), rec_get_converted_size(), TRUE, trx_sys_multiple_tablespace_format, ut_a, and ut_ad.
Referenced by btr_cur_search_to_nth_level().
02764 : TRUE if success */ 02765 dtuple_t* entry, /* in: index entry to insert */ 02766 dict_index_t* index, /* in: index where to insert */ 02767 ulint space, /* in: space id where to insert */ 02768 ulint page_no,/* in: page number where to insert */ 02769 que_thr_t* thr) /* in: query thread */ 02770 { 02771 ulint err; 02772 02773 ut_a(trx_sys_multiple_tablespace_format); 02774 ut_ad(dtuple_check_typed(entry)); 02775 02776 ut_a(!(index->type & DICT_CLUSTERED)); 02777 02778 if (rec_get_converted_size(index, entry) 02779 >= page_get_free_space_of_empty( 02780 dict_table_is_comp(index->table)) / 2) { 02781 return(FALSE); 02782 } 02783 02784 err = ibuf_insert_low(BTR_MODIFY_PREV, entry, index, space, page_no, 02785 thr); 02786 if (err == DB_FAIL) { 02787 err = ibuf_insert_low(BTR_MODIFY_TREE, entry, index, space, 02788 page_no, thr); 02789 } 02790 02791 if (err == DB_SUCCESS) { 02792 #ifdef UNIV_IBUF_DEBUG 02793 /* fprintf(stderr, "Ibuf insert for page no %lu of index %s\n", 02794 page_no, index->name); */ 02795 #endif 02796 return(TRUE); 02797 02798 } else { 02799 ut_a(err == DB_STRONG_FAIL); 02800 02801 return(FALSE); 02802 } 02803 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool ibuf_inside | ( | void | ) |
Definition at line 259 of file ibuf0ibuf.c.
References thr_local_get_in_ibuf_field().
Referenced by btr_cur_search_to_nth_level(), buf_page_get_gen(), buf_page_get_known_nowait(), buf_page_init_for_read(), buf_page_optimistic_get_func(), buf_read_ibuf_merge_pages(), fil_io(), ibuf_contract_ext(), ibuf_delete_rec(), ibuf_free_excess_pages(), ibuf_header_page_get(), ibuf_insert_to_index_page(), ibuf_rec_get_page_no(), ibuf_rec_get_space(), ibuf_rec_get_volume(), and ibuf_tree_root_get().
00261 : TRUE if inside an insert buffer routine: for instance, 00262 a read-ahead of non-ibuf pages is then forbidden */ 00263 { 00264 return(*thr_local_get_in_ibuf_field()); 00265 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool ibuf_is_empty | ( | void | ) |
Definition at line 3456 of file ibuf0ibuf.c.
References data, FALSE, ibuf, ibuf_enter(), ibuf_exit(), ibuf_mutex, ibuf_tree_root_get(), mtr_commit(), mtr_start(), mutex_enter, mutex_exit(), page_get_n_recs(), page_t, TRUE, ut_a, and UT_LIST_GET_FIRST.
Referenced by innobase_start_or_create_for_mysql().
03458 : TRUE if empty */ 03459 { 03460 ibuf_data_t* data; 03461 ibool is_empty; 03462 page_t* root; 03463 mtr_t mtr; 03464 03465 ibuf_enter(); 03466 03467 mutex_enter(&ibuf_mutex); 03468 03469 data = UT_LIST_GET_FIRST(ibuf->data_list); 03470 03471 mtr_start(&mtr); 03472 03473 root = ibuf_tree_root_get(data, 0, &mtr); 03474 03475 if (page_get_n_recs(root) == 0) { 03476 03477 is_empty = TRUE; 03478 03479 if (data->empty == FALSE) { 03480 fprintf(stderr, 03481 "InnoDB: Warning: insert buffer tree is empty but the data struct does not\n" 03482 "InnoDB: know it. This condition is legal if the master thread has not yet\n" 03483 "InnoDB: run to completion.\n"); 03484 } 03485 } else { 03486 ut_a(data->empty == FALSE); 03487 03488 is_empty = FALSE; 03489 } 03490 03491 mtr_commit(&mtr); 03492 03493 ut_a(data->space == 0); 03494 03495 mutex_exit(&ibuf_mutex); 03496 03497 ibuf_exit(); 03498 03499 return(is_empty); 03500 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void ibuf_merge_or_delete_for_page | ( | page_t * | page, | |
| ulint | space, | |||
| ulint | page_no, | |||
| ibool | update_ibuf_bitmap | |||
| ) |
Definition at line 3030 of file ibuf0ibuf.c.
References yaSSL::block, BTR_MODIFY_LEAF, btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_after_last_in_tree(), btr_pcur_is_after_last_on_page(), btr_pcur_is_on_user_rec(), btr_pcur_open_on_user_rec(), buf_block_align(), buf_frame_align(), BUF_KEEP_OLD, buf_page_get_known_nowait(), buf_page_print(), FALSE, fil_decr_pending_ibuf_merges(), fil_inc_pending_ibuf_merges(), fil_page_get_type(), FIL_PAGE_INDEX, fil_space_get_ibuf_data(), fsp_descr_page(), IBUF_BITMAP_BUFFERED, IBUF_BITMAP_FREE, ibuf_bitmap_get_map_page(), ibuf_bitmap_page_get_bits(), ibuf_bitmap_page_set_bits(), ibuf_build_entry_from_ibuf_rec(), ibuf_delete_rec(), ibuf_dummy_index_free(), ibuf_enter(), ibuf_exit(), ibuf_fixed_addr_page(), ibuf_insert_to_index_page(), ibuf_mutex, ibuf_new_search_tuple_build(), ibuf_rec_get_page_no(), ibuf_rec_get_space(), ibuf_search_tuple_build(), mem_heap_create, mem_heap_free, mtr_commit(), mtr_start(), mutex_enter, mutex_exit(), NULL, PAGE_CUR_GE, page_dir_calc_reserved_space(), page_get_max_trx_id(), page_header_reset_last_insert(), page_t, page_update_max_trx_id(), rec_get_converted_size(), rec_print_old(), rw_lock_x_lock_move_ownership(), RW_X_LATCH, SRV_FORCE_NO_IBUF_MERGE, srv_force_recovery, SYNC_TREE_NODE, TRUE, trx_doublewrite_must_reset_space_ids, trx_sys_hdr_page(), trx_sys_multiple_tablespace_format, UNIV_PAGE_SIZE, ut_a, ut_ad, and ut_print_timestamp().
Referenced by buf_page_create(), buf_page_io_complete(), and buf_read_ibuf_merge_pages().
03032 : if page has been read from disk, pointer to 03033 the page x-latched, else NULL */ 03034 ulint space, /* in: space id of the index page */ 03035 ulint page_no,/* in: page number of the index page */ 03036 ibool update_ibuf_bitmap)/* in: normally this is set to TRUE, but if 03037 we have deleted or are deleting the tablespace, then we 03038 naturally do not want to update a non-existent bitmap 03039 page */ 03040 { 03041 mem_heap_t* heap; 03042 btr_pcur_t pcur; 03043 dtuple_t* entry; 03044 dtuple_t* search_tuple; 03045 rec_t* ibuf_rec; 03046 buf_block_t* block; 03047 page_t* bitmap_page; 03048 ibuf_data_t* ibuf_data; 03049 ulint n_inserts; 03050 #ifdef UNIV_IBUF_DEBUG 03051 ulint volume; 03052 #endif 03053 ibool tablespace_being_deleted = FALSE; 03054 ibool corruption_noticed = FALSE; 03055 mtr_t mtr; 03056 03057 if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { 03058 03059 return; 03060 } 03061 03062 #ifdef UNIV_LOG_DEBUG 03063 if (space % 2 != 0) { 03064 03065 fputs("No ibuf operation in a replicate space\n", stderr); 03066 03067 return; 03068 } 03069 #endif 03070 if (ibuf_fixed_addr_page(space, page_no) || fsp_descr_page(page_no) 03071 || trx_sys_hdr_page(space, page_no)) { 03072 return; 03073 } 03074 03075 if (update_ibuf_bitmap) { 03076 /* If the following returns FALSE, we get the counter 03077 incremented, and must decrement it when we leave this 03078 function. When the counter is > 0, that prevents tablespace 03079 from being dropped. */ 03080 03081 tablespace_being_deleted = fil_inc_pending_ibuf_merges(space); 03082 03083 if (tablespace_being_deleted) { 03084 /* Do not try to read the bitmap page from space; 03085 just delete the ibuf records for the page */ 03086 03087 page = NULL; 03088 update_ibuf_bitmap = FALSE; 03089 } 03090 } 03091 03092 if (update_ibuf_bitmap) { 03093 mtr_start(&mtr); 03094 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr); 03095 03096 if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no, 03097 IBUF_BITMAP_BUFFERED, &mtr)) { 03098 /* No inserts buffered for this page */ 03099 mtr_commit(&mtr); 03100 03101 if (!tablespace_being_deleted) { 03102 fil_decr_pending_ibuf_merges(space); 03103 } 03104 03105 return; 03106 } 03107 mtr_commit(&mtr); 03108 } 03109 03110 /* Currently the insert buffer of space 0 takes care of inserts to all 03111 tablespaces */ 03112 03113 ibuf_data = fil_space_get_ibuf_data(0); 03114 03115 ibuf_enter(); 03116 03117 heap = mem_heap_create(512); 03118 03119 if (!trx_sys_multiple_tablespace_format) { 03120 ut_a(trx_doublewrite_must_reset_space_ids); 03121 search_tuple = ibuf_search_tuple_build(space, page_no, heap); 03122 } else { 03123 search_tuple = ibuf_new_search_tuple_build(space, page_no, 03124 heap); 03125 } 03126 03127 if (page) { 03128 /* Move the ownership of the x-latch on the page to this OS 03129 thread, so that we can acquire a second x-latch on it. This 03130 is needed for the insert operations to the index page to pass 03131 the debug checks. */ 03132 03133 block = buf_block_align(page); 03134 rw_lock_x_lock_move_ownership(&(block->lock)); 03135 03136 if (fil_page_get_type(page) != FIL_PAGE_INDEX) { 03137 03138 corruption_noticed = TRUE; 03139 03140 ut_print_timestamp(stderr); 03141 03142 mtr_start(&mtr); 03143 03144 fputs(" InnoDB: Dump of the ibuf bitmap page:\n", 03145 stderr); 03146 03147 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, 03148 &mtr); 03149 buf_page_print(bitmap_page); 03150 03151 mtr_commit(&mtr); 03152 03153 fputs("\nInnoDB: Dump of the page:\n", stderr); 03154 03155 buf_page_print(page); 03156 03157 fprintf(stderr, 03158 "InnoDB: Error: corruption in the tablespace. Bitmap shows insert\n" 03159 "InnoDB: buffer records to page n:o %lu though the page\n" 03160 "InnoDB: type is %lu, which is not an index page!\n" 03161 "InnoDB: We try to resolve the problem by skipping the insert buffer\n" 03162 "InnoDB: merge for this page. Please run CHECK TABLE on your tables\n" 03163 "InnoDB: to determine if they are corrupt after this.\n\n" 03164 "InnoDB: Please submit a detailed bug report to http://bugs.mysql.com\n\n", 03165 (ulong) page_no, 03166 (ulong) fil_page_get_type(page)); 03167 } 03168 } 03169 03170 n_inserts = 0; 03171 #ifdef UNIV_IBUF_DEBUG 03172 volume = 0; 03173 #endif 03174 loop: 03175 mtr_start(&mtr); 03176 03177 if (page) { 03178 ibool success = buf_page_get_known_nowait(RW_X_LATCH, page, 03179 BUF_KEEP_OLD, 03180 __FILE__, __LINE__, 03181 &mtr); 03182 ut_a(success); 03183 #ifdef UNIV_SYNC_DEBUG 03184 buf_page_dbg_add_level(page, SYNC_TREE_NODE); 03185 #endif /* UNIV_SYNC_DEBUG */ 03186 } 03187 03188 /* Position pcur in the insert buffer at the first entry for this 03189 index page */ 03190 btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE, 03191 BTR_MODIFY_LEAF, &pcur, &mtr); 03192 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 03193 ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr)); 03194 03195 goto reset_bit; 03196 } 03197 03198 for (;;) { 03199 ut_ad(btr_pcur_is_on_user_rec(&pcur, &mtr)); 03200 03201 ibuf_rec = btr_pcur_get_rec(&pcur); 03202 03203 /* Check if the entry is for this index page */ 03204 if (ibuf_rec_get_page_no(ibuf_rec) != page_no 03205 || ibuf_rec_get_space(ibuf_rec) != space) { 03206 if (page) { 03207 page_header_reset_last_insert(page, &mtr); 03208 } 03209 goto reset_bit; 03210 } 03211 03212 if (corruption_noticed) { 03213 fputs("InnoDB: Discarding record\n ", stderr); 03214 rec_print_old(stderr, ibuf_rec); 03215 fputs("\n from the insert buffer!\n\n", stderr); 03216 } else if (page) { 03217 /* Now we have at pcur a record which should be 03218 inserted to the index page; NOTE that the call below 03219 copies pointers to fields in ibuf_rec, and we must 03220 keep the latch to the ibuf_rec page until the 03221 insertion is finished! */ 03222 dict_index_t* dummy_index; 03223 dulint max_trx_id = page_get_max_trx_id( 03224 buf_frame_align(ibuf_rec)); 03225 page_update_max_trx_id(page, max_trx_id); 03226 03227 entry = ibuf_build_entry_from_ibuf_rec(ibuf_rec, 03228 heap, &dummy_index); 03229 #ifdef UNIV_IBUF_DEBUG 03230 volume += rec_get_converted_size(dummy_index, entry) 03231 + page_dir_calc_reserved_space(1); 03232 ut_a(volume <= 4 * UNIV_PAGE_SIZE 03233 / IBUF_PAGE_SIZE_PER_FREE_SPACE); 03234 #endif 03235 ibuf_insert_to_index_page(entry, page, 03236 dummy_index, &mtr); 03237 ibuf_dummy_index_free(dummy_index); 03238 } 03239 03240 n_inserts++; 03241 03242 /* Delete the record from ibuf */ 03243 if (ibuf_delete_rec(space, page_no, &pcur, search_tuple, 03244 &mtr)) { 03245 /* Deletion was pessimistic and mtr was committed: 03246 we start from the beginning again */ 03247 03248 goto loop; 03249 } 03250 03251 if (btr_pcur_is_after_last_on_page(&pcur, &mtr)) { 03252 mtr_commit(&mtr); 03253 btr_pcur_close(&pcur); 03254 03255 goto loop; 03256 } 03257 } 03258 03259 reset_bit: 03260 #ifdef UNIV_IBUF_DEBUG 03261 if (ibuf_count_get(space, page_no) > 0) { 03262 /* btr_print_tree(ibuf_data->index->tree, 100); 03263 ibuf_print(); */ 03264 } 03265 #endif 03266 if (update_ibuf_bitmap) { 03267 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr); 03268 ibuf_bitmap_page_set_bits(bitmap_page, page_no, 03269 IBUF_BITMAP_BUFFERED, FALSE, &mtr); 03270 if (page) { 03271 ulint old_bits = ibuf_bitmap_page_get_bits(bitmap_page, 03272 page_no, IBUF_BITMAP_FREE, &mtr); 03273 ulint new_bits = ibuf_index_page_calc_free(page); 03274 #ifdef UNIV_IBUF_DEBUG 03275 /* fprintf(stderr, "Old bits %lu new bits %lu max size %lu\n", 03276 old_bits, new_bits, 03277 page_get_max_insert_size_after_reorganize(page, 1)); */ 03278 #endif 03279 if (old_bits != new_bits) { 03280 ibuf_bitmap_page_set_bits(bitmap_page, page_no, 03281 IBUF_BITMAP_FREE, 03282 new_bits, &mtr); 03283 } 03284 } 03285 } 03286 #ifdef UNIV_IBUF_DEBUG 03287 /* fprintf(stderr, 03288 "Ibuf merge %lu records volume %lu to page no %lu\n", 03289 n_inserts, volume, page_no); */ 03290 #endif 03291 mtr_commit(&mtr); 03292 btr_pcur_close(&pcur); 03293 mem_heap_free(heap); 03294 03295 /* Protect our statistics keeping from race conditions */ 03296 mutex_enter(&ibuf_mutex); 03297 03298 ibuf_data->n_merges++; 03299 ibuf_data->n_merged_recs += n_inserts; 03300 03301 mutex_exit(&ibuf_mutex); 03302 03303 if (update_ibuf_bitmap && !tablespace_being_deleted) { 03304 03305 fil_decr_pending_ibuf_merges(space); 03306 } 03307 03308 ibuf_exit(); 03309 #ifdef UNIV_IBUF_DEBUG 03310 ut_a(ibuf_count_get(space, page_no) == 0); 03311 #endif 03312 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 966 of file ibuf0ibuf.c.
References FALSE, fil_space_get_type(), FIL_TABLESPACE, ibuf_bitmap_get_map_page(), IBUF_BITMAP_IBUF, ibuf_bitmap_page_get_bits(), ibuf_fixed_addr_page(), mtr_commit(), mtr_start(), page_t, recv_no_ibuf_operations, TRUE, and ut_ad.
Referenced by buf_page_get_gen(), buf_page_optimistic_get_func(), fil_io(), and fsp_fill_free_list().
00968 : TRUE if level 2 or level 3 page */ 00969 ulint space, /* in: space id */ 00970 ulint page_no)/* in: page number */ 00971 { 00972 page_t* bitmap_page; 00973 mtr_t mtr; 00974 ibool ret; 00975 00976 if (recv_no_ibuf_operations) { 00977 /* Recovery is running: no ibuf operations should be 00978 performed */ 00979 00980 return(FALSE); 00981 } 00982 00983 if (ibuf_fixed_addr_page(space, page_no)) { 00984 00985 return(TRUE); 00986 } 00987 00988 if (space != 0) { 00989 /* Currently we only have an ibuf tree in space 0 */ 00990 00991 return(FALSE); 00992 } 00993 00994 ut_ad(fil_space_get_type(space) == FIL_TABLESPACE); 00995 00996 mtr_start(&mtr); 00997 00998 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr); 00999 01000 ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, 01001 &mtr); 01002 mtr_commit(&mtr); 01003 01004 return(ret); 01005 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1011 of file ibuf0ibuf.c.
References FALSE, ibuf_bitmap_get_map_page(), IBUF_BITMAP_IBUF, ibuf_bitmap_page_get_bits(), ibuf_fixed_addr_page(), page_t, and TRUE.
Referenced by buf_page_init_for_read().
01013 : TRUE if level 2 or level 3 page */ 01014 ulint space, /* in: space id */ 01015 ulint page_no,/* in: page number */ 01016 mtr_t* mtr) /* in: mtr which will contain an x-latch to the 01017 bitmap page if the page is not one of the fixed 01018 address ibuf pages */ 01019 { 01020 page_t* bitmap_page; 01021 ibool ret; 01022 01023 #ifdef UNIV_LOG_DEBUG 01024 if (space % 2 != 0) { 01025 01026 fputs("No ibuf in a replicate space\n", stderr); 01027 01028 return(FALSE); 01029 } 01030 #endif 01031 if (ibuf_fixed_addr_page(space, page_no)) { 01032 01033 return(TRUE); 01034 } 01035 01036 bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr); 01037 01038 ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, 01039 mtr); 01040 return(ret); 01041 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void ibuf_print | ( | FILE * | file | ) |
Definition at line 3506 of file ibuf0ibuf.c.
References data, ibuf, ibuf_mutex, mutex_enter, UT_LIST_GET_FIRST, and UT_LIST_GET_NEXT.
Referenced by srv_printf_innodb_monitor().
03508 : file where to print */ 03509 { 03510 ibuf_data_t* data; 03511 #ifdef UNIV_IBUF_DEBUG 03512 ulint i; 03513 #endif 03514 03515 mutex_enter(&ibuf_mutex); 03516 03517 data = UT_LIST_GET_FIRST(ibuf->data_list); 03518 03519 while (data) { 03520 fprintf(file, 03521 "Ibuf for space %lu: size %lu, free list len %lu, seg size %lu,", 03522 (ulong) data->space, (ulong) data->size, 03523 (ulong) data->free_list_len, 03524 (ulong) data->seg_size); 03525 03526 if (data->empty) { 03527 fputs(" is empty\n", file); 03528 } else { 03529 fputs(" is not empty\n", file); 03530 } 03531 fprintf(file, 03532 "Ibuf for space %lu: size %lu, free list len %lu, seg size %lu,\n" 03533 "%lu inserts, %lu merged recs, %lu merges\n", 03534 (ulong) data->space, 03535 (ulong) data->size, 03536 (ulong) data->free_list_len, 03537 (ulong) data->seg_size, 03538 (ulong) data->n_inserts, 03539 (ulong) data->n_merged_recs, 03540 (ulong) data->n_merges); 03541 #ifdef UNIV_IBUF_DEBUG 03542 for (i = 0; i < IBUF_COUNT_N_PAGES; i++) { 03543 if (ibuf_count_get(data->space, i) > 0) { 03544 03545 fprintf(stderr, 03546 "Ibuf count for page %lu is %lu\n", 03547 (ulong) i, 03548 (ulong) ibuf_count_get(data->space, i)); 03549 } 03550 } 03551 #endif 03552 data = UT_LIST_GET_NEXT(data_list, data); 03553 } 03554 03555 mutex_exit(&ibuf_mutex); 03556 }
Here is the caller graph for this function:

| void ibuf_reset_free_bits | ( | dict_index_t * | index, | |
| page_t * | page | |||
| ) |
Definition at line 879 of file ibuf0ibuf.c.
References ibuf_set_free_bits(), and index().
Referenced by btr_discard_only_page_on_level(), btr_lift_page_up(), btr_page_split_and_insert(), and btr_root_raise_and_insert().
00881 : index */ 00882 page_t* page) /* in: index page; free bits are set to 0 if 00883 the index is non-clustered and non-unique and 00884 the page level is 0 */ 00885 { 00886 ibuf_set_free_bits(index->type, page, 0, ULINT_UNDEFINED); 00887 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 862 of file ibuf0ibuf.c.
References ibuf_set_free_bits().
Referenced by btr_create().
00864 : index type */ 00865 page_t* page) /* in: index page; free bits are set to 0 if the index 00866 is non-clustered and non-unique and the page level is 00867 0 */ 00868 { 00869 ibuf_set_free_bits(type, page, 0, ULINT_UNDEFINED); 00870 }
Here is the call graph for this function:

Here is the caller graph for this function:

| UNIV_INLINE ibool ibuf_should_try | ( | dict_index_t * | index, | |
| ulint | ignore_sec_unique | |||
| ) |
| void ibuf_update_free_bits_for_two_pages_low | ( | dict_index_t * | index, | |
| page_t * | page1, | |||
| page_t * | page2, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 922 of file ibuf0ibuf.c.
References ibuf_bitmap_mutex, ibuf_set_free_bits_low(), index(), mutex_enter, and mutex_exit().
Referenced by btr_page_split_and_insert().
00924 : index */ 00925 page_t* page1, /* in: index page */ 00926 page_t* page2, /* in: index page */ 00927 mtr_t* mtr) /* in: mtr */ 00928 { 00929 ulint state; 00930 00931 /* As we have to x-latch two random bitmap pages, we have to acquire 00932 the bitmap mutex to prevent a deadlock with a similar operation 00933 performed by another OS thread. */ 00934 00935 mutex_enter(&ibuf_bitmap_mutex); 00936 00937 state = ibuf_index_page_calc_free(page1); 00938 00939 ibuf_set_free_bits_low(index->type, page1, state, mtr); 00940 00941 state = ibuf_index_page_calc_free(page2); 00942 00943 ibuf_set_free_bits_low(index->type, page2, state, mtr); 00944 00945 mutex_exit(&ibuf_bitmap_mutex); 00946 }
Here is the call graph for this function:

Here is the caller graph for this function:

| UNIV_INLINE void ibuf_update_free_bits_if_full | ( | dict_index_t * | index, | |
| page_t * | page, | |||
| ulint | max_ins_size, | |||
| ulint | increase | |||
| ) |
Referenced by btr_compress(), and btr_cur_optimistic_insert().
Here is the caller graph for this function:

| void ibuf_update_free_bits_low | ( | dict_index_t * | index, | |
| page_t * | page, | |||
| ulint | max_ins_size, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 895 of file ibuf0ibuf.c.
References ibuf_set_free_bits_low(), and index().
Referenced by btr_cur_optimistic_delete().
00897 : index */ 00898 page_t* page, /* in: index page */ 00899 ulint max_ins_size, /* in: value of maximum insert size 00900 with reorganize before the latest 00901 operation performed to the page */ 00902 mtr_t* mtr) /* in: mtr */ 00903 { 00904 ulint before; 00905 ulint after; 00906 00907 before = ibuf_index_page_calc_free_bits(max_ins_size); 00908 00909 after = ibuf_index_page_calc_free(page); 00910 00911 if (before != after) { 00912 ibuf_set_free_bits_low(index->type, page, after, mtr); 00913 } 00914 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void ibuf_update_max_tablespace_id | ( | void | ) |
Definition at line 2449 of file ibuf0ibuf.c.
References btr_pcur_get_rec(), btr_pcur_is_before_first_on_page(), btr_pcur_move_to_prev(), btr_pcur_open_at_index_side(), BTR_SEARCH_LEAF, dict_table_is_comp(), FALSE, fil_set_max_space_id_if_bigger(), fil_space_get_ibuf_data(), ibuf_enter(), ibuf_exit(), mach_read_from_4(), mtr_commit(), mtr_start(), rec_get_nth_field_old(), dict_index_struct::table, TRUE, and ut_a.
Referenced by innobase_start_or_create_for_mysql().
02451 { 02452 ulint max_space_id; 02453 rec_t* rec; 02454 byte* field; 02455 ulint len; 02456 ibuf_data_t* ibuf_data; 02457 dict_index_t* ibuf_index; 02458 btr_pcur_t pcur; 02459 mtr_t mtr; 02460 02461 ibuf_data = fil_space_get_ibuf_data(0); 02462 02463 ibuf_index = ibuf_data->index; 02464 ut_a(!dict_table_is_comp(ibuf_index->table)); 02465 02466 ibuf_enter(); 02467 02468 mtr_start(&mtr); 02469 02470 btr_pcur_open_at_index_side(FALSE, ibuf_index, BTR_SEARCH_LEAF, 02471 &pcur, TRUE, &mtr); 02472 btr_pcur_move_to_prev(&pcur, &mtr); 02473 02474 if (btr_pcur_is_before_first_on_page(&pcur, &mtr)) { 02475 /* The tree is empty */ 02476 02477 max_space_id = 0; 02478 } else { 02479 rec = btr_pcur_get_rec(&pcur); 02480 02481 field = rec_get_nth_field_old(rec, 0, &len); 02482 02483 ut_a(len == 4); 02484 02485 max_space_id = mach_read_from_4(field); 02486 } 02487 02488 mtr_commit(&mtr); 02489 ibuf_exit(); 02490 02491 /* printf("Maximum space id in insert buffer %lu\n", max_space_id); */ 02492 02493 fil_set_max_space_id_if_bigger(max_space_id); 02494 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 141 of file ibuf0ibuf.c.
Referenced by ibuf_contract_after_insert(), ibuf_contract_ext(), ibuf_data_init_for_space(), ibuf_data_sizes_update(), ibuf_init_at_db_start(), ibuf_insert_low(), ibuf_is_empty(), ibuf_print(), and ibuf_validate_low().
1.4.7

