3275
# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
3276
ibuf_get_entry_counter_func(space,page_no,rec,mtr,exact_leaf)
3277
#else /* UNIV_DEBUG */
3278
# define ibuf_get_entry_counter(space,page_no,rec,mtr,exact_leaf) \
3279
ibuf_get_entry_counter_func(space,page_no,rec,exact_leaf)
3260
3282
/****************************************************************//**
3261
Set the counter field in entry to the correct value based on the current
3283
Calculate the counter field for an entry based on the current
3262
3284
last record in ibuf for (space, page_no).
3263
@return FALSE if we should abort this insertion to ibuf */
3285
@return the counter field, or ULINT_UNDEFINED
3286
if we should abort this insertion to ibuf */
3266
ibuf_set_entry_counter(
3267
/*===================*/
3268
dtuple_t* entry, /*!< in/out: entry to patch */
3289
ibuf_get_entry_counter_func(
3290
/*========================*/
3269
3291
ulint space, /*!< in: space id of entry */
3270
3292
ulint page_no, /*!< in: page number of entry */
3271
btr_pcur_t* pcur, /*!< in: pcur positioned on the record
3272
found by btr_pcur_open(.., entry,
3273
PAGE_CUR_LE, ..., pcur, ...) */
3274
ibool is_optimistic, /*!< in: is this an optimistic insert */
3275
mtr_t* mtr) /*!< in: mtr */
3293
const rec_t* rec, /*!< in: the record preceding the
3296
mtr_t* mtr, /*!< in: mini-transaction */
3297
#endif /* UNIV_DEBUG */
3298
ibool only_leaf) /*!< in: TRUE if this is the only
3299
leaf page that can contain entries
3300
for (space,page_no), that is, there
3301
was no exact match for (space,page_no)
3302
in the node pointer */
3281
/* pcur points to either a user rec or to a page's infimum record. */
3282
3304
ut_ad(ibuf_inside(mtr));
3283
ut_ad(mtr_memo_contains(mtr, btr_pcur_get_block(pcur),
3284
MTR_MEMO_PAGE_X_FIX));
3285
ut_ad(page_validate(btr_pcur_get_page(pcur), ibuf->index));
3287
if (btr_pcur_is_on_user_rec(pcur)) {
3289
counter = ibuf_get_entry_counter_low(
3290
mtr, btr_pcur_get_rec(pcur), space, page_no);
3292
if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3293
/* The record lacks a counter field.
3294
Such old records must be merged before
3295
new records can be buffered. */
3299
} else if (btr_pcur_is_before_first_in_tree(pcur, mtr)) {
3300
/* Ibuf tree is either completely empty, or the insert
3301
position is at the very first record of a non-empty tree. In
3302
either case we have no previous records for (space,
3306
} else if (btr_pcur_is_before_first_on_page(pcur)) {
3307
btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur);
3309
if (cursor->low_match < 3) {
3310
/* If low_match < 3, we know that the father node
3311
pointer did not contain the searched for (space,
3312
page_no), which means that the search ended on the
3313
right page regardless of the counter value, and
3314
since we're at the infimum record, there are no
3315
existing records. */
3325
ut_a(cursor->ibuf_cnt != ULINT_UNDEFINED);
3327
page = btr_pcur_get_page(pcur);
3328
prev_page_no = btr_page_get_prev(page, mtr);
3330
ut_a(prev_page_no != FIL_NULL);
3332
block = buf_page_get(
3333
IBUF_SPACE_ID, 0, prev_page_no,
3336
buf_block_dbg_add_level(block, SYNC_IBUF_TREE_NODE);
3338
prev_page = buf_block_get_frame(block);
3340
rec = page_rec_get_prev(
3341
page_get_supremum_rec(prev_page));
3343
ut_ad(page_rec_is_user_rec(rec));
3345
counter = ibuf_get_entry_counter_low(
3346
mtr, rec, space, page_no);
3348
if (UNIV_UNLIKELY(counter == ULINT_UNDEFINED)) {
3349
/* The record lacks a counter field.
3350
Such old records must be merged before
3351
new records can be buffered. */
3356
if (counter < cursor->ibuf_cnt) {
3357
/* Search ended on the wrong page. */
3359
if (is_optimistic) {
3360
/* In an optimistic insert, we can
3361
shift the insert position to the left
3362
page, since it only needs an X-latch
3363
on the page itself, which the
3364
original search acquired for us. */
3367
ibuf->index, rec, block,
3368
btr_pcur_get_btr_cur(pcur));
3370
/* We can't shift the insert
3371
position to the left page in a
3372
pessimistic insert since it would
3373
require an X-latch on the left
3374
page's left page, so we have to
3380
/* The counter field in the father node is
3381
the same as we would insert; we don't know
3382
whether the insert should go to this page or
3383
the left page (the later fields can differ),
3384
so refuse the insert. */
3305
ut_ad(mtr_memo_contains_page(mtr, rec, MTR_MEMO_PAGE_X_FIX));
3306
ut_ad(page_validate(page_align(rec), ibuf->index));
3308
if (page_rec_is_supremum(rec)) {
3309
/* This is just for safety. The record should be a
3310
page infimum or a user record. */
3312
return(ULINT_UNDEFINED);
3313
} else if (!page_rec_is_infimum(rec)) {
3314
return(ibuf_get_entry_counter_low(mtr, rec, space, page_no));
3315
} else if (only_leaf
3316
|| fil_page_get_prev(page_align(rec)) == FIL_NULL) {
3317
/* The parent node pointer did not contain the
3318
searched for (space, page_no), which means that the
3319
search ended on the correct page regardless of the
3320
counter value, and since we're at the infimum record,
3321
there are no existing records. */
3390
/* The cursor is not positioned at or before a user record. */
3324
/* We used to read the previous page here. It would
3325
break the latching order, because the caller has
3326
buffer-fixed an insert buffer bitmap page. */
3327
return(ULINT_UNDEFINED);
3394
/* Patch counter value in already built entry. */
3395
field = dtuple_get_nth_field(entry, 3);
3396
data = dfield_get_data(field);
3398
mach_write_to_2(data + IBUF_REC_OFFSET_COUNTER, counter);
3403
3331
/*********************************************************************//**
3607
/* Patch correct counter value to the entry to insert. This can
3608
change the insert position, which can result in the need to abort in
3611
&& !ibuf_set_entry_counter(ibuf_entry, space, page_no, &pcur,
3612
mode == BTR_MODIFY_PREV, &mtr)) {
3536
/* Patch correct counter value to the entry to
3537
insert. This can change the insert position, which can
3538
result in the need to abort in some cases. */
3539
ulint counter = ibuf_get_entry_counter(
3540
space, page_no, btr_pcur_get_rec(&pcur), &mtr,
3541
btr_pcur_get_btr_cur(&pcur)->low_match
3542
< IBUF_REC_FIELD_METADATA);
3545
if (counter == ULINT_UNDEFINED) {
3614
ibuf_mtr_commit(&bitmap_mtr);
3547
ibuf_mtr_commit(&bitmap_mtr);
3551
field = dtuple_get_nth_field(
3552
ibuf_entry, IBUF_REC_FIELD_METADATA);
3554
(byte*) dfield_get_data(field)
3555
+ IBUF_REC_OFFSET_COUNTER, counter);
3619
3558
/* Set the bitmap bit denoting that the insert buffer contains