84
83
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
85
84
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
87
block = btr_pcur_get_block(cursor);
88
86
index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
90
88
page_cursor = btr_pcur_get_page_cur(cursor);
93
91
page = page_align(rec);
94
92
offs = page_offset(rec);
96
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_S_FIX)
97
|| mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
94
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
96
|| mtr_memo_contains(mtr, buf_block_align(page),
97
MTR_MEMO_PAGE_X_FIX));
98
98
ut_a(cursor->latch_mode != BTR_NO_LATCHES);
100
100
if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) {
137
137
index, rec, &cursor->old_n_fields,
138
138
&cursor->old_rec_buf, &cursor->buf_size);
140
cursor->block_when_stored = block;
141
cursor->modify_clock = buf_block_get_modify_clock(block);
140
cursor->block_when_stored = buf_block_align(page);
141
cursor->modify_clock = buf_block_get_modify_clock(
142
cursor->block_when_stored);
144
145
/******************************************************************
145
146
Copies the stored position of a pcur to another pcur. */
148
149
btr_pcur_copy_stored_position(
149
150
/*==========================*/
183
184
GREATER than the user record which was the predecessor of the supremum.
184
185
(4) cursor was positioned before the first or after the last in an empty tree:
185
186
restores to before first or after the last in the tree. */
188
189
btr_pcur_restore_position(
189
190
/*======================*/
219
(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
220
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
221
cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
222
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
222
224
/* In these cases we do not try an optimistic restoration,
223
225
but always do a search */
226
228
cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
227
229
index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
229
cursor->block_when_stored = btr_pcur_get_block(cursor);
231
cursor->block_when_stored
232
= buf_block_align(btr_pcur_get_page(cursor));
234
237
ut_a(cursor->old_rec);
235
238
ut_a(cursor->old_n_fields);
240
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
237
242
if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
238
243
|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
239
244
/* Try optimistic restoration */
241
246
if (UNIV_LIKELY(buf_page_optimistic_get(
243
cursor->block_when_stored,
248
cursor->block_when_stored, page,
244
249
cursor->modify_clock, mtr))) {
245
250
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
246
251
#ifdef UNIV_SYNC_DEBUG
247
buf_block_dbg_add_level(btr_pcur_get_block(cursor),
252
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
249
253
#endif /* UNIV_SYNC_DEBUG */
250
254
if (cursor->rel_pos == BTR_PCUR_ON) {
251
255
#ifdef UNIV_DEBUG
253
const ulint* offsets1;
254
const ulint* offsets2;
255
259
#endif /* UNIV_DEBUG */
256
260
cursor->latch_mode = latch_mode;
257
261
#ifdef UNIV_DEBUG
303
307
cursor->search_mode = old_mode;
305
309
if (cursor->rel_pos == BTR_PCUR_ON
306
&& btr_pcur_is_on_user_rec(cursor)
310
&& btr_pcur_is_on_user_rec(cursor, mtr)
307
311
&& 0 == cmp_dtuple_rec(tuple, btr_pcur_get_rec(cursor),
309
313
btr_pcur_get_rec(cursor), index,
313
317
the cursor can now be on a different page! But we can retain
314
318
the value of old_rec */
316
cursor->block_when_stored = btr_pcur_get_block(cursor);
320
cursor->block_when_stored = buf_block_align(
321
btr_pcur_get_page(cursor));
317
322
cursor->modify_clock = buf_block_get_modify_clock(
318
323
cursor->block_when_stored);
319
324
cursor->old_stored = BTR_PCUR_OLD_STORED;
340
345
NOTE! In the case of BTR_LEAF_MODIFY, there should not exist changes
341
346
made by the current mini-transaction to the data protected by the
342
347
cursor latch, as then the latch must not be released until mtr_commit. */
345
350
btr_pcur_release_leaf(
346
351
/*==================*/
347
352
btr_pcur_t* cursor, /* in: persistent cursor */
348
353
mtr_t* mtr) /* in: mtr */
352
357
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
353
358
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
355
block = btr_pcur_get_block(cursor);
360
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
357
btr_leaf_page_release(block, cursor->latch_mode, mtr);
362
btr_leaf_page_release(page, cursor->latch_mode, mtr);
359
364
cursor->latch_mode = BTR_NO_LATCHES;
366
371
latch on the current page, and bufferunfixes it. Note that there must not be
367
372
modifications on the current page, as then the x-latch can be released only in
371
376
btr_pcur_move_to_next_page(
372
377
/*=======================*/
374
379
last record of the current page */
375
380
mtr_t* mtr) /* in: mtr */
381
buf_block_t* next_block;
384
387
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
385
388
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
386
ut_ad(btr_pcur_is_after_last_on_page(cursor));
389
ut_ad(btr_pcur_is_after_last_on_page(cursor, mtr));
388
391
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
390
393
page = btr_pcur_get_page(cursor);
391
395
next_page_no = btr_page_get_next(page, mtr);
392
space = buf_block_get_space(btr_pcur_get_block(cursor));
393
zip_size = buf_block_get_zip_size(btr_pcur_get_block(cursor));
396
space = buf_frame_get_space_id(page);
395
398
ut_ad(next_page_no != FIL_NULL);
397
next_block = btr_block_get(space, zip_size, next_page_no,
398
cursor->latch_mode, mtr);
399
next_page = buf_block_get_frame(next_block);
400
next_page = btr_page_get(space, next_page_no, cursor->latch_mode, mtr);
400
401
#ifdef UNIV_BTR_DEBUG
402
ut_a(btr_page_get_prev(next_page, mtr) == buf_frame_get_page_no(page));
403
#endif /* UNIV_BTR_DEBUG */
401
404
ut_a(page_is_comp(next_page) == page_is_comp(page));
402
ut_a(btr_page_get_prev(next_page, mtr)
403
== buf_block_get_page_no(btr_pcur_get_block(cursor)));
404
#endif /* UNIV_BTR_DEBUG */
405
next_block->check_index_page_at_flush = TRUE;
407
btr_leaf_page_release(btr_pcur_get_block(cursor),
408
cursor->latch_mode, mtr);
410
page_cur_set_before_first(next_block, btr_pcur_get_page_cur(cursor));
405
buf_block_align(next_page)->check_index_page_at_flush = TRUE;
407
btr_leaf_page_release(page, cursor->latch_mode, mtr);
409
page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor));
412
411
page_check_dir(next_page);
421
420
return, but it may happen that the cursor is not positioned on the last
422
421
record of any page, because the structure of the tree may have changed
423
422
during the time when the cursor had no latches. */
426
425
btr_pcur_move_backward_from_page(
427
426
/*=============================*/
429
428
record of the current page */
430
429
mtr_t* mtr) /* in: mtr */
435
buf_block_t* prev_block;
439
438
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
440
439
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
441
ut_ad(btr_pcur_is_before_first_on_page(cursor));
440
ut_ad(btr_pcur_is_before_first_on_page(cursor, mtr));
442
441
ut_ad(!btr_pcur_is_before_first_in_tree(cursor, mtr));
444
443
latch_mode = cursor->latch_mode;
466
465
page = btr_pcur_get_page(cursor);
468
467
prev_page_no = btr_page_get_prev(page, mtr);
469
space = buf_block_get_space(btr_pcur_get_block(cursor));
471
if (prev_page_no == FIL_NULL) {
472
} else if (btr_pcur_is_before_first_on_page(cursor)) {
474
prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
476
btr_leaf_page_release(btr_pcur_get_block(cursor),
479
page_cur_set_after_last(prev_block,
468
space = buf_frame_get_space_id(page);
470
if (btr_pcur_is_before_first_on_page(cursor, mtr)
471
&& (prev_page_no != FIL_NULL)) {
473
prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
475
btr_leaf_page_release(page, latch_mode, mtr);
477
page_cur_set_after_last(prev_page,
480
478
btr_pcur_get_page_cur(cursor));
479
} else if (prev_page_no != FIL_NULL) {
483
481
/* The repositioned cursor did not end on an infimum record on
484
482
a page. Cursor repositioning acquired a latch also on the
485
483
previous page, but we do not need the latch: release it. */
487
prev_block = btr_pcur_get_btr_cur(cursor)->left_block;
485
prev_page = btr_pcur_get_btr_cur(cursor)->left_page;
489
btr_leaf_page_release(prev_block, latch_mode, mtr);
487
btr_leaf_page_release(prev_page, latch_mode, mtr);
492
490
cursor->latch_mode = latch_mode;
513
511
cursor->old_stored = BTR_PCUR_OLD_NOT_STORED;
515
if (btr_pcur_is_before_first_on_page(cursor)) {
513
if (btr_pcur_is_before_first_on_page(cursor, mtr)) {
517
515
if (btr_pcur_is_before_first_in_tree(cursor, mtr)) {
536
534
in the first case sets the cursor after last in tree, and in the latter case
537
535
before first in tree. The latching mode must be BTR_SEARCH_LEAF or
538
536
BTR_MODIFY_LEAF. */
541
539
btr_pcur_open_on_user_rec(
542
540
/*======================*/
543
541
dict_index_t* index, /* in: index */
544
const dtuple_t* tuple, /* in: tuple on which search done */
542
dtuple_t* tuple, /* in: tuple on which search done */
545
543
ulint mode, /* in: PAGE_CUR_L, ... */
546
544
ulint latch_mode, /* in: BTR_SEARCH_LEAF or
547
545
BTR_MODIFY_LEAF */
554
552
if ((mode == PAGE_CUR_GE) || (mode == PAGE_CUR_G)) {
556
if (btr_pcur_is_after_last_on_page(cursor)) {
554
if (btr_pcur_is_after_last_on_page(cursor, mtr)) {
558
556
btr_pcur_move_to_next_user_rec(cursor, mtr);