2640
2622
ulint sum_sizes;
2644
/* Perform dirty reads of ibuf->size and ibuf->max_size, to
2645
reduce ibuf_mutex contention. ibuf->max_size remains constant
2646
after ibuf_init_at_db_start(), but ibuf->size should be
2647
protected by ibuf_mutex. Given that ibuf->size fits in a
2648
machine word, this should be OK; at worst we are doing some
2649
excessive ibuf_contract() or occasionally skipping a
2652
max_size = ibuf->max_size;
2654
if (size < max_size + IBUF_CONTRACT_ON_INSERT_NON_SYNC) {
2625
mutex_enter(&ibuf_mutex);
2627
if (ibuf->size < ibuf->max_size + IBUF_CONTRACT_ON_INSERT_NON_SYNC) {
2628
mutex_exit(&ibuf_mutex);
2658
sync = (size >= max_size + IBUF_CONTRACT_ON_INSERT_SYNC);
2635
if (ibuf->size >= ibuf->max_size + IBUF_CONTRACT_ON_INSERT_SYNC) {
2640
mutex_exit(&ibuf_mutex);
2660
2642
/* Contract at least entry_size many bytes */
2646
while ((size > 0) && (sum_sizes < entry_size)) {
2666
2648
size = ibuf_contract(sync);
2667
2649
sum_sizes += size;
2668
} while (size > 0 && sum_sizes < entry_size);
2671
2653
/*********************************************************************//**
3520
3506
err = btr_cur_optimistic_insert(BTR_NO_LOCKING_FLAG, cursor,
3521
3507
ibuf_entry, &ins_rec,
3522
3508
&dummy_big_rec, 0, thr, &mtr);
3523
block = btr_cur_get_block(cursor);
3524
ut_ad(buf_block_get_space(block) == IBUF_SPACE_ID);
3526
/* If this is the root page, update ibuf->empty. */
3527
if (UNIV_UNLIKELY(buf_block_get_page_no(block)
3528
== FSP_IBUF_TREE_ROOT_PAGE_NO)) {
3529
const page_t* page_root = buf_block_get_frame(block);
3531
ut_ad(page_get_space_id(page_root) == IBUF_SPACE_ID);
3532
ut_ad(page_get_page_no(page_root)
3533
== FSP_IBUF_TREE_ROOT_PAGE_NO);
3535
ibuf->empty = (page_get_n_recs(page_root) == 0);
3509
if (err == DB_SUCCESS && op != IBUF_OP_DELETE) {
3510
/* Update the page max trx id field */
3511
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
3512
thr_get_trx(thr)->id, &mtr);
3538
3515
ut_ad(mode == BTR_MODIFY_TREE);
3550
3527
ibuf_entry, &ins_rec,
3551
3528
&dummy_big_rec, 0, thr, &mtr);
3552
mutex_exit(&ibuf_pessimistic_insert_mutex);
3529
if (err == DB_SUCCESS && op != IBUF_OP_DELETE) {
3530
/* Update the page max trx id field */
3531
page_update_max_trx_id(btr_cur_get_block(cursor), NULL,
3532
thr_get_trx(thr)->id, &mtr);
3553
3535
ibuf_size_update(root, &mtr);
3554
mutex_exit(&ibuf_mutex);
3555
ibuf->empty = (page_get_n_recs(root) == 0);
3557
block = btr_cur_get_block(cursor);
3558
ut_ad(buf_block_get_space(block) == IBUF_SPACE_ID);
3561
if (err == DB_SUCCESS && op != IBUF_OP_DELETE) {
3562
/* Update the page max trx id field */
3563
page_update_max_trx_id(block, NULL,
3564
thr_get_trx(thr)->id, &mtr);
3568
3539
#ifdef UNIV_IBUF_COUNT_DEBUG
3569
3540
if (err == DB_SUCCESS) {
3570
3541
fprintf(stderr,
3753
3737
from the insert buffer. */
3756
ibuf_insert_to_index_page_low(
3757
/*==========================*/
3758
const dtuple_t* entry, /*!< in: buffered entry to insert */
3759
buf_block_t* block, /*!< in/out: index page where the buffered
3760
entry should be placed */
3761
dict_index_t* index, /*!< in: record descriptor */
3762
mtr_t* mtr, /*!< in/out: mtr */
3763
page_cur_t* page_cur)/*!< in/out: cursor positioned on the record
3764
after which to insert the buffered entry */
3770
const page_t* bitmap_page;
3774
(page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
3778
/* If the record did not fit, reorganize */
3780
btr_page_reorganize(block, index, mtr);
3781
page_cur_search(block, index, entry, PAGE_CUR_LE, page_cur);
3783
/* This time the record must fit */
3786
(page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
3790
page = buf_block_get_frame(block);
3792
ut_print_timestamp(stderr);
3795
" InnoDB: Error: Insert buffer insert fails;"
3796
" page free %lu, dtuple size %lu\n",
3797
(ulong) page_get_max_insert_size(page, 1),
3798
(ulong) rec_get_converted_size(index, entry, 0));
3799
fputs("InnoDB: Cannot insert index record ", stderr);
3800
dtuple_print(stderr, entry);
3801
fputs("\nInnoDB: The table where this index record belongs\n"
3802
"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
3803
"InnoDB: that table.\n", stderr);
3805
space = page_get_space_id(page);
3806
zip_size = buf_block_get_zip_size(block);
3807
page_no = page_get_page_no(page);
3809
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
3810
old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
3811
IBUF_BITMAP_FREE, mtr);
3814
"InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n",
3815
(ulong) space, (ulong) page_no,
3816
(ulong) zip_size, (ulong) old_bits);
3818
fputs("InnoDB: Submit a detailed bug report"
3819
" to http://bugs.mysql.com\n", stderr);
3822
/************************************************************************
3823
During merge, inserts to an index page a secondary index entry extracted
3824
from the insert buffer. */
3827
3740
ibuf_insert_to_index_page(
3828
3741
/*======================*/
3829
const dtuple_t* entry, /*!< in: buffered entry to insert */
3742
dtuple_t* entry, /*!< in: buffered entry to insert */
3830
3743
buf_block_t* block, /*!< in/out: index page where the buffered entry
3831
3744
should be placed */
3832
3745
dict_index_t* index, /*!< in: record descriptor */
3885
3805
low_match = page_cur_search(block, index, entry,
3886
3806
PAGE_CUR_LE, &page_cur);
3888
if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
3808
if (low_match == dtuple_get_n_fields(entry)) {
3892
3809
page_zip_des_t* page_zip;
3894
3811
rec = page_cur_get_rec(&page_cur);
3897
row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
3898
ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
3900
heap = mem_heap_create(1024);
3902
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
3904
update = row_upd_build_sec_rec_difference_binary(
3905
index, entry, rec, NULL, heap);
3907
3812
page_zip = buf_block_get_page_zip(block);
3909
if (update->n_fields == 0) {
3910
/* The records only differ in the delete-mark.
3911
Clear the delete-mark, like we did before
3912
Bug #56680 was fixed. */
3913
btr_cur_set_deleted_flag_for_ibuf(
3914
rec, page_zip, FALSE, mtr);
3916
mem_heap_free(heap);
3814
btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, FALSE, mtr);
3816
rec = page_cur_tuple_insert(&page_cur, entry, index, 0, mtr);
3818
if (UNIV_LIKELY(rec != NULL)) {
3920
/* Copy the info bits. Clear the delete-mark. */
3921
update->info_bits = rec_get_info_bits(rec, page_is_comp(page));
3922
update->info_bits &= ~REC_INFO_DELETED_FLAG;
3924
/* We cannot invoke btr_cur_optimistic_update() here,
3925
because we do not have a btr_cur_t or que_thr_t,
3926
as the insert buffer merge occurs at a very low level. */
3927
if (!row_upd_changes_field_size_or_external(index, offsets,
3929
&& (!page_zip || btr_cur_update_alloc_zip(
3930
page_zip, block, index,
3931
rec_offs_size(offsets), FALSE, mtr))) {
3932
/* This is the easy case. Do something similar
3933
to btr_cur_update_in_place(). */
3934
row_upd_rec_in_place(rec, index, offsets,
3936
goto updated_in_place;
3822
/* If the record did not fit, reorganize */
3824
btr_page_reorganize(block, index, mtr);
3825
page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur);
3827
/* This time the record must fit */
3829
(!page_cur_tuple_insert(&page_cur, entry, index,
3835
ut_print_timestamp(stderr);
3838
" InnoDB: Error: Insert buffer insert"
3839
" fails; page free %lu,"
3840
" dtuple size %lu\n",
3841
(ulong) page_get_max_insert_size(
3843
(ulong) rec_get_converted_size(
3845
fputs("InnoDB: Cannot insert index record ",
3847
dtuple_print(stderr, entry);
3848
fputs("\nInnoDB: The table where"
3849
" this index record belongs\n"
3850
"InnoDB: is now probably corrupt."
3851
" Please run CHECK TABLE on\n"
3852
"InnoDB: that table.\n", stderr);
3854
space = page_get_space_id(page);
3855
zip_size = buf_block_get_zip_size(block);
3856
page_no = page_get_page_no(page);
3858
bitmap_page = ibuf_bitmap_get_map_page(
3859
space, page_no, zip_size, mtr);
3860
old_bits = ibuf_bitmap_page_get_bits(
3861
bitmap_page, page_no, zip_size,
3862
IBUF_BITMAP_FREE, mtr);
3865
"InnoDB: space %lu, page %lu,"
3866
" zip_size %lu, bitmap bits %lu\n",
3867
(ulong) space, (ulong) page_no,
3868
(ulong) zip_size, (ulong) old_bits);
3870
fputs("InnoDB: Submit a detailed bug report"
3871
" to http://bugs.mysql.com\n", stderr);
3939
/* A collation may identify values that differ in
3941
Some examples (1 or 2 bytes):
3942
utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I
3943
utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S
3944
utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
3946
latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S
3948
Examples of a character (3-byte UTF-8 sequence)
3949
identified with 2 or 4 characters (1-byte UTF-8 sequences):
3951
utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO
3952
utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN
3955
/* Delete the different-length record, and insert the
3958
lock_rec_store_on_page_infimum(block, rec);
3959
page_cur_delete_rec(&page_cur, index, offsets, mtr);
3960
page_cur_move_to_prev(&page_cur);
3961
mem_heap_free(heap);
3963
ibuf_insert_to_index_page_low(entry, block, index, mtr,
3965
lock_rec_restore_from_page_infimum(block, rec, block);
3967
ibuf_insert_to_index_page_low(entry, block, index, mtr,
3997
3901
rec = page_cur_get_rec(&page_cur);
3998
3902
page_zip = page_cur_get_page_zip(&page_cur);
4000
/* Delete mark the old index record. According to a
4001
comment in row_upd_sec_index_entry(), it can already
4002
have been delete marked if a lock wait occurred in
4003
row_ins_index_entry() in a previous invocation of
4004
row_upd_sec_index_entry(). */
4007
(!rec_get_deleted_flag(
4008
rec, dict_table_is_comp(index->table)))) {
4009
btr_cur_set_deleted_flag_for_ibuf(rec, page_zip,
3904
btr_cur_set_deleted_flag_for_ibuf(rec, page_zip, TRUE, mtr);
4013
ut_print_timestamp(stderr);
4014
fputs(" InnoDB: unable to find a record to delete-mark\n",
4016
fputs("InnoDB: tuple ", stderr);
4017
dtuple_print(stderr, entry);
4019
"InnoDB: record ", stderr);
4020
rec_print(stderr, page_cur_get_rec(&page_cur), index);
4023
"InnoDB: Submit a detailed bug report"
4024
" to http://bugs.mysql.com\n", stderr);
3906
/* This can happen benignly in some situations. */