mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1
This commit is contained in:
commit
a6d0581275
80 changed files with 1844 additions and 1692 deletions
|
|
@ -20,6 +20,7 @@ Created 6/2/1994 Heikki Tuuri
|
|||
#include "rem0cmp.h"
|
||||
#include "lock0lock.h"
|
||||
#include "ibuf0ibuf.h"
|
||||
#include "trx0trx.h"
|
||||
|
||||
/*
|
||||
Latching strategy of the InnoDB B-tree
|
||||
|
|
@ -137,13 +138,13 @@ btr_root_get(
|
|||
ulint space;
|
||||
ulint root_page_no;
|
||||
page_t* root;
|
||||
ibool comp = UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp;
|
||||
|
||||
space = dict_tree_get_space(tree);
|
||||
root_page_no = dict_tree_get_page(tree);
|
||||
|
||||
root = btr_page_get(space, root_page_no, RW_X_LATCH, mtr);
|
||||
ut_a(page_is_comp(root) == comp);
|
||||
ut_a(!!page_is_comp(root) ==
|
||||
UT_LIST_GET_FIRST(tree->tree_indexes)->table->comp);
|
||||
|
||||
return(root);
|
||||
}
|
||||
|
|
@ -163,21 +164,19 @@ btr_get_prev_user_rec(
|
|||
page_t* page;
|
||||
page_t* prev_page;
|
||||
ulint prev_page_no;
|
||||
rec_t* prev_rec;
|
||||
ulint space;
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
|
||||
if (page_get_infimum_rec(page) != rec) {
|
||||
if (!page_rec_is_infimum(rec)) {
|
||||
|
||||
prev_rec = page_rec_get_prev(rec);
|
||||
rec_t* prev_rec = page_rec_get_prev(rec);
|
||||
|
||||
if (page_get_infimum_rec(page) != prev_rec) {
|
||||
if (!page_rec_is_infimum(prev_rec)) {
|
||||
|
||||
return(prev_rec);
|
||||
}
|
||||
}
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
prev_page_no = btr_page_get_prev(page, mtr);
|
||||
space = buf_frame_get_space_id(page);
|
||||
|
||||
|
|
@ -192,9 +191,7 @@ btr_get_prev_user_rec(
|
|||
MTR_MEMO_PAGE_X_FIX)));
|
||||
ut_a(page_is_comp(prev_page) == page_is_comp(page));
|
||||
|
||||
prev_rec = page_rec_get_prev(page_get_supremum_rec(prev_page));
|
||||
|
||||
return(prev_rec);
|
||||
return(page_rec_get_prev(page_get_supremum_rec(prev_page)));
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -215,21 +212,19 @@ btr_get_next_user_rec(
|
|||
page_t* page;
|
||||
page_t* next_page;
|
||||
ulint next_page_no;
|
||||
rec_t* next_rec;
|
||||
ulint space;
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
|
||||
if (page_get_supremum_rec(page) != rec) {
|
||||
if (!page_rec_is_supremum(rec)) {
|
||||
|
||||
next_rec = page_rec_get_next(rec);
|
||||
rec_t* next_rec = page_rec_get_next(rec);
|
||||
|
||||
if (page_get_supremum_rec(page) != next_rec) {
|
||||
if (!page_rec_is_supremum(next_rec)) {
|
||||
|
||||
return(next_rec);
|
||||
}
|
||||
}
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
next_page_no = btr_page_get_next(page, mtr);
|
||||
space = buf_frame_get_space_id(page);
|
||||
|
||||
|
|
@ -244,9 +239,7 @@ btr_get_next_user_rec(
|
|||
MTR_MEMO_PAGE_X_FIX)));
|
||||
|
||||
ut_a(page_is_comp(next_page) == page_is_comp(page));
|
||||
next_rec = page_rec_get_next(page_get_infimum_rec(next_page));
|
||||
|
||||
return(next_rec);
|
||||
return(page_rec_get_next(page_get_infimum_rec(next_page)));
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -573,8 +566,7 @@ btr_page_get_father_for_rec(
|
|||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
|
||||
MTR_MEMO_X_LOCK));
|
||||
ut_a(user_rec != page_get_supremum_rec(page));
|
||||
ut_a(user_rec != page_get_infimum_rec(page));
|
||||
ut_a(page_rec_is_user_rec(user_rec));
|
||||
|
||||
ut_ad(dict_tree_get_page(tree) != buf_frame_get_page_no(page));
|
||||
|
||||
|
|
@ -598,6 +590,7 @@ btr_page_get_father_for_rec(
|
|||
|
||||
if (btr_node_ptr_get_child_page_no(node_ptr, offsets) !=
|
||||
buf_frame_get_page_no(page)) {
|
||||
rec_t* print_rec;
|
||||
fputs("InnoDB: Dump of the child page:\n", stderr);
|
||||
buf_page_print(buf_frame_align(page));
|
||||
fputs("InnoDB: Dump of the parent page:\n", stderr);
|
||||
|
|
@ -612,11 +605,10 @@ btr_page_get_father_for_rec(
|
|||
(ulong)
|
||||
btr_node_ptr_get_child_page_no(node_ptr, offsets),
|
||||
(ulong) buf_frame_get_page_no(page));
|
||||
offsets = rec_get_offsets(page_rec_get_next(
|
||||
page_get_infimum_rec(page)), index,
|
||||
print_rec = page_rec_get_next(page_get_infimum_rec(page));
|
||||
offsets = rec_get_offsets(print_rec, index,
|
||||
offsets, ULINT_UNDEFINED, &heap);
|
||||
page_rec_print(page_rec_get_next(page_get_infimum_rec(page)),
|
||||
offsets);
|
||||
page_rec_print(print_rec, offsets);
|
||||
offsets = rec_get_offsets(node_ptr, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
page_rec_print(node_ptr, offsets);
|
||||
|
|
@ -663,7 +655,7 @@ btr_create(
|
|||
ulint type, /* in: type of the index */
|
||||
ulint space, /* in: space where created */
|
||||
dulint index_id,/* in: index id */
|
||||
ibool comp, /* in: TRUE=compact page format */
|
||||
ulint comp, /* in: nonzero=compact page format */
|
||||
mtr_t* mtr) /* in: mini-transaction handle */
|
||||
{
|
||||
ulint page_no;
|
||||
|
|
@ -854,11 +846,12 @@ btr_page_reorganize_low(
|
|||
|
||||
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
|
||||
MTR_MEMO_PAGE_X_FIX));
|
||||
ut_ad(!!page_is_comp(page) == index->table->comp);
|
||||
data_size1 = page_get_data_size(page);
|
||||
max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
|
||||
|
||||
/* Write the log record */
|
||||
mlog_open_and_write_index(mtr, page, index, index->table->comp
|
||||
mlog_open_and_write_index(mtr, page, index, page_is_comp(page)
|
||||
? MLOG_COMP_PAGE_REORGANIZE
|
||||
: MLOG_PAGE_REORGANIZE, 0);
|
||||
|
||||
|
|
@ -877,7 +870,7 @@ btr_page_reorganize_low(
|
|||
/* Recreate the page: note that global data on page (possible
|
||||
segment headers, next page-field, etc.) is preserved intact */
|
||||
|
||||
page_create(page, mtr, index->table->comp);
|
||||
page_create(page, mtr, page_is_comp(page));
|
||||
buf_block_align(page)->check_index_page_at_flush = TRUE;
|
||||
|
||||
/* Copy the records from the temporary space to the recreated page;
|
||||
|
|
@ -1070,7 +1063,7 @@ btr_root_raise_and_insert(
|
|||
as there is no lower alphabetical limit to records in the leftmost
|
||||
node of a level: */
|
||||
|
||||
btr_set_min_rec_mark(node_ptr_rec, cursor->index->table->comp, mtr);
|
||||
btr_set_min_rec_mark(node_ptr_rec, page_is_comp(root), mtr);
|
||||
|
||||
/* Free the memory heap */
|
||||
mem_heap_free(heap);
|
||||
|
|
@ -1151,7 +1144,6 @@ btr_page_get_split_rec_to_right(
|
|||
{
|
||||
page_t* page;
|
||||
rec_t* insert_point;
|
||||
rec_t* supremum;
|
||||
|
||||
page = btr_cur_get_page(cursor);
|
||||
insert_point = btr_cur_get_rec(cursor);
|
||||
|
|
@ -1160,13 +1152,23 @@ btr_page_get_split_rec_to_right(
|
|||
the previous insert on the same page, we assume that there is a
|
||||
pattern of sequential inserts here. */
|
||||
|
||||
if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) {
|
||||
if (UNIV_LIKELY(page_header_get_ptr(page, PAGE_LAST_INSERT)
|
||||
== insert_point)) {
|
||||
|
||||
supremum = page_get_supremum_rec(page);
|
||||
|
||||
if (page_rec_get_next(insert_point) != supremum
|
||||
&& page_rec_get_next(page_rec_get_next(insert_point))
|
||||
!= supremum) {
|
||||
rec_t* next_rec;
|
||||
|
||||
next_rec = page_rec_get_next(insert_point);
|
||||
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
split_at_new:
|
||||
/* Split at the new record to insert */
|
||||
*split_rec = NULL;
|
||||
} else {
|
||||
rec_t* next_next_rec = page_rec_get_next(next_rec);
|
||||
if (page_rec_is_supremum(next_next_rec)) {
|
||||
|
||||
goto split_at_new;
|
||||
}
|
||||
|
||||
/* If there are >= 2 user records up from the insert
|
||||
point, split all but 1 off. We want to keep one because
|
||||
|
|
@ -1175,12 +1177,8 @@ btr_page_get_split_rec_to_right(
|
|||
search position just by looking at the records on this
|
||||
page. */
|
||||
|
||||
*split_rec = page_rec_get_next(
|
||||
page_rec_get_next(insert_point));
|
||||
} else {
|
||||
/* Else split at the new record to insert */
|
||||
*split_rec = NULL;
|
||||
}
|
||||
*split_rec = next_next_rec;
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
|
@ -1220,7 +1218,7 @@ btr_page_get_sure_split_rec(
|
|||
page = btr_cur_get_page(cursor);
|
||||
|
||||
insert_size = rec_get_converted_size(cursor->index, tuple);
|
||||
free_space = page_get_free_space_of_empty(cursor->index->table->comp);
|
||||
free_space = page_get_free_space_of_empty(page_is_comp(page));
|
||||
|
||||
/* free_space is now the free space of a created new page */
|
||||
|
||||
|
|
@ -1276,21 +1274,22 @@ btr_page_get_sure_split_rec(
|
|||
supremum record of page */
|
||||
|
||||
if (rec == ins_rec) {
|
||||
next_rec = NULL;
|
||||
rec = NULL;
|
||||
|
||||
goto func_exit;
|
||||
} else if (rec == NULL) {
|
||||
next_rec = page_rec_get_next(ins_rec);
|
||||
} else {
|
||||
next_rec = page_rec_get_next(rec);
|
||||
}
|
||||
if (next_rec != page_get_supremum_rec(page)) {
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(next_rec);
|
||||
ut_ad(next_rec);
|
||||
if (!page_rec_is_supremum(next_rec)) {
|
||||
rec = next_rec;
|
||||
}
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
func_exit:
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(rec);
|
||||
|
|
@ -1329,13 +1328,12 @@ btr_page_insert_fits(
|
|||
|
||||
ut_ad(!split_rec == !offsets);
|
||||
ut_ad(!offsets
|
||||
|| cursor->index->table->comp == rec_offs_comp(offsets));
|
||||
|| !page_is_comp(page) == !rec_offs_comp(offsets));
|
||||
ut_ad(!offsets
|
||||
|| rec_offs_validate(split_rec, cursor->index, offsets));
|
||||
ut_ad(page_is_comp(page) == cursor->index->table->comp);
|
||||
|
||||
insert_size = rec_get_converted_size(cursor->index, tuple);
|
||||
free_space = page_get_free_space_of_empty(cursor->index->table->comp);
|
||||
free_space = page_get_free_space_of_empty(page_is_comp(page));
|
||||
|
||||
/* free_space is now the free space of a created new page */
|
||||
|
||||
|
|
@ -1832,14 +1830,15 @@ void
|
|||
btr_set_min_rec_mark_log(
|
||||
/*=====================*/
|
||||
rec_t* rec, /* in: record */
|
||||
ibool comp, /* TRUE=compact record format */
|
||||
ulint comp, /* nonzero=compact record format */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
mlog_write_initial_log_record(rec,
|
||||
comp ? MLOG_COMP_REC_MIN_MARK : MLOG_REC_MIN_MARK, mtr);
|
||||
|
||||
/* Write rec offset as a 2-byte ulint */
|
||||
mlog_catenate_ulint(mtr, rec - buf_frame_align(rec), MLOG_2BYTES);
|
||||
mlog_catenate_ulint(mtr, ut_align_offset(rec, UNIV_PAGE_SIZE),
|
||||
MLOG_2BYTES);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
@ -1852,7 +1851,7 @@ btr_parse_set_min_rec_mark(
|
|||
/* out: end of log record or NULL */
|
||||
byte* ptr, /* in: buffer */
|
||||
byte* end_ptr,/* in: buffer end */
|
||||
ibool comp, /* in: TRUE=compact page format */
|
||||
ulint comp, /* in: nonzero=compact page format */
|
||||
page_t* page, /* in: page or NULL */
|
||||
mtr_t* mtr) /* in: mtr or NULL */
|
||||
{
|
||||
|
|
@ -1864,6 +1863,8 @@ btr_parse_set_min_rec_mark(
|
|||
}
|
||||
|
||||
if (page) {
|
||||
ut_a(!page_is_comp(page) == !comp);
|
||||
|
||||
rec = page + mach_read_from_2(ptr);
|
||||
|
||||
btr_set_min_rec_mark(rec, comp, mtr);
|
||||
|
|
@ -1879,7 +1880,7 @@ void
|
|||
btr_set_min_rec_mark(
|
||||
/*=================*/
|
||||
rec_t* rec, /* in: record */
|
||||
ibool comp, /* in: TRUE=compact page format */
|
||||
ulint comp, /* in: nonzero=compact page format */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
ulint info_bits;
|
||||
|
|
@ -2008,11 +2009,12 @@ btr_compress(
|
|||
ulint max_ins_size;
|
||||
ulint max_ins_size_reorg;
|
||||
ulint level;
|
||||
ibool comp = cursor->index->table->comp;
|
||||
ulint comp;
|
||||
|
||||
page = btr_cur_get_page(cursor);
|
||||
tree = btr_cur_get_tree(cursor);
|
||||
ut_a(comp == page_is_comp(page));
|
||||
comp = page_is_comp(page);
|
||||
ut_a(!!comp == cursor->index->table->comp);
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
|
||||
MTR_MEMO_X_LOCK));
|
||||
|
|
@ -2055,7 +2057,7 @@ btr_compress(
|
|||
|
||||
n_recs = page_get_n_recs(page);
|
||||
data_size = page_get_data_size(page);
|
||||
ut_a(page_is_comp(merge_page) == page_is_comp(page));
|
||||
ut_a(page_is_comp(merge_page) == comp);
|
||||
|
||||
max_ins_size_reorg = page_get_max_insert_size_after_reorganize(
|
||||
merge_page, n_recs);
|
||||
|
|
@ -2108,7 +2110,7 @@ btr_compress(
|
|||
rec_get_offsets(node_ptr, cursor->index,
|
||||
offsets_, ULINT_UNDEFINED, &heap),
|
||||
right_page_no, mtr);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
btr_node_ptr_delete(tree, merge_page, mtr);
|
||||
|
|
@ -2250,10 +2252,9 @@ btr_discard_page(
|
|||
|
||||
node_ptr = page_rec_get_next(page_get_infimum_rec(merge_page));
|
||||
|
||||
ut_ad(node_ptr != page_get_supremum_rec(merge_page));
|
||||
ut_ad(page_rec_is_user_rec(node_ptr));
|
||||
|
||||
btr_set_min_rec_mark(node_ptr,
|
||||
cursor->index->table->comp, mtr);
|
||||
btr_set_min_rec_mark(node_ptr, page_is_comp(merge_page), mtr);
|
||||
}
|
||||
|
||||
btr_node_ptr_delete(tree, page, mtr);
|
||||
|
|
@ -2274,6 +2275,7 @@ btr_discard_page(
|
|||
ut_ad(btr_check_node_ptr(tree, merge_page, mtr));
|
||||
}
|
||||
|
||||
#ifdef UNIV_BTR_PRINT
|
||||
/*****************************************************************
|
||||
Prints size info of a B-tree. */
|
||||
|
||||
|
|
@ -2401,14 +2403,15 @@ btr_print_tree(
|
|||
root = btr_root_get(tree, &mtr);
|
||||
|
||||
btr_print_recursive(tree, root, width, &heap, &offsets, &mtr);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
btr_validate_tree(tree);
|
||||
btr_validate_tree(tree, NULL);
|
||||
}
|
||||
#endif /* UNIV_BTR_PRINT */
|
||||
|
||||
/****************************************************************
|
||||
Checks that the node pointer to a page is appropriate. */
|
||||
|
|
@ -2496,8 +2499,8 @@ btr_index_rec_validate(
|
|||
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
|
||||
if (index->type & DICT_UNIVERSAL) {
|
||||
|
||||
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
|
||||
/* The insert buffer index tree can contain records from any
|
||||
other index: we cannot check the number of fields or
|
||||
their length */
|
||||
|
|
@ -2505,9 +2508,18 @@ btr_index_rec_validate(
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(!!page_is_comp(page) != index->table->comp)) {
|
||||
btr_index_rec_validate_report(page, rec, index);
|
||||
fprintf(stderr, "InnoDB: compact flag=%lu, should be %lu\n",
|
||||
(ulong) !!page_is_comp(page),
|
||||
(ulong) index->table->comp);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
n = dict_index_get_n_fields(index);
|
||||
|
||||
if (!index->table->comp && rec_get_n_fields_old(rec) != n) {
|
||||
if (!page_is_comp(page)
|
||||
&& UNIV_UNLIKELY(rec_get_n_fields_old(rec) != n)) {
|
||||
btr_index_rec_validate_report(page, rec, index);
|
||||
fprintf(stderr, "InnoDB: has %lu fields, should have %lu\n",
|
||||
(ulong) rec_get_n_fields_old(rec), (ulong) n);
|
||||
|
|
@ -2554,14 +2566,14 @@ btr_index_rec_validate(
|
|||
rec_print_new(stderr, rec, offsets);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(TRUE);
|
||||
|
|
@ -2649,6 +2661,7 @@ btr_validate_level(
|
|||
/*===============*/
|
||||
/* out: TRUE if ok */
|
||||
dict_tree_t* tree, /* in: index tree */
|
||||
trx_t* trx, /* in: transaction or NULL */
|
||||
ulint level) /* in: level number */
|
||||
{
|
||||
ulint space;
|
||||
|
|
@ -2696,6 +2709,11 @@ btr_validate_level(
|
|||
/* Now we are on the desired level. Loop through the pages on that
|
||||
level. */
|
||||
loop:
|
||||
if (trx_is_interrupted(trx)) {
|
||||
mtr_commit(&mtr);
|
||||
mem_heap_free(heap);
|
||||
return(ret);
|
||||
}
|
||||
mem_heap_empty(heap);
|
||||
offsets = offsets2 = NULL;
|
||||
mtr_x_lock(dict_tree_get_lock(tree), &mtr);
|
||||
|
|
@ -2765,7 +2783,7 @@ loop:
|
|||
if (level > 0 && left_page_no == FIL_NULL) {
|
||||
ut_a(REC_INFO_MIN_REC_FLAG & rec_get_info_bits(
|
||||
page_rec_get_next(page_get_infimum_rec(page)),
|
||||
index->table->comp));
|
||||
page_is_comp(page)));
|
||||
}
|
||||
|
||||
if (buf_frame_get_page_no(page) != dict_tree_get_page(tree)) {
|
||||
|
|
@ -2921,7 +2939,7 @@ node_ptr_fails:
|
|||
mtr_commit(&mtr);
|
||||
|
||||
if (right_page_no != FIL_NULL) {
|
||||
ibool comp = page_is_comp(page);
|
||||
ulint comp = page_is_comp(page);
|
||||
mtr_start(&mtr);
|
||||
|
||||
page = btr_page_get(space, right_page_no, RW_X_LATCH, &mtr);
|
||||
|
|
@ -2941,7 +2959,8 @@ ibool
|
|||
btr_validate_tree(
|
||||
/*==============*/
|
||||
/* out: TRUE if ok */
|
||||
dict_tree_t* tree) /* in: tree */
|
||||
dict_tree_t* tree, /* in: tree */
|
||||
trx_t* trx) /* in: transaction or NULL */
|
||||
{
|
||||
mtr_t mtr;
|
||||
page_t* root;
|
||||
|
|
@ -2954,9 +2973,8 @@ btr_validate_tree(
|
|||
root = btr_root_get(tree, &mtr);
|
||||
n = btr_page_get_level(root, &mtr);
|
||||
|
||||
for (i = 0; i <= n; i++) {
|
||||
|
||||
if (!btr_validate_level(tree, n - i)) {
|
||||
for (i = 0; i <= n && !trx_is_interrupted(trx); i++) {
|
||||
if (!btr_validate_level(tree, trx, n - i)) {
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ Created 10/16/1994 Heikki Tuuri
|
|||
#include "ibuf0ibuf.h"
|
||||
#include "lock0lock.h"
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* 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;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ulint btr_cur_n_non_sea = 0;
|
||||
ulint btr_cur_n_sea = 0;
|
||||
|
|
@ -431,7 +431,7 @@ retry_page_get:
|
|||
cursor->thr)) {
|
||||
/* Insertion to the insert buffer succeeded */
|
||||
cursor->flag = BTR_CUR_INSERT_TO_IBUF;
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return;
|
||||
|
|
@ -505,8 +505,9 @@ retry_page_get:
|
|||
|
||||
if (level > 0) {
|
||||
/* x-latch the page */
|
||||
ut_a(page_is_comp(btr_page_get(space,
|
||||
page_no, RW_X_LATCH, mtr))
|
||||
page = btr_page_get(space,
|
||||
page_no, RW_X_LATCH, mtr);
|
||||
ut_a(!!page_is_comp(page)
|
||||
== index->table->comp);
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +526,7 @@ retry_page_get:
|
|||
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
|
|
@ -681,7 +682,7 @@ btr_cur_open_at_index_side(
|
|||
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
|
@ -762,7 +763,7 @@ btr_cur_open_at_rnd_pos(
|
|||
page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
|
@ -879,6 +880,7 @@ btr_cur_ins_lock_and_undo(
|
|||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/*****************************************************************
|
||||
Report information about a transaction. */
|
||||
static
|
||||
|
|
@ -896,6 +898,7 @@ btr_cur_trx_report(
|
|||
dict_index_name_print(stderr, trx, index);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/*****************************************************************
|
||||
Tries to perform an insert to a page in an index tree, next to cursor.
|
||||
|
|
@ -945,12 +948,13 @@ btr_cur_optimistic_insert(
|
|||
fputs("InnoDB: Error in a tuple to insert into ", stderr);
|
||||
dict_index_name_print(stderr, thr_get_trx(thr), index);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (btr_cur_print_record_ops && thr) {
|
||||
btr_cur_trx_report(thr_get_trx(thr), index, "insert into ");
|
||||
dtuple_print(stderr, entry);
|
||||
}
|
||||
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
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);
|
||||
|
|
@ -961,7 +965,7 @@ calculate_sizes_again:
|
|||
rec_size = rec_get_converted_size(index, entry);
|
||||
|
||||
if (rec_size >=
|
||||
ut_min(page_get_free_space_of_empty(index->table->comp) / 2,
|
||||
ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,
|
||||
REC_MAX_DATA_SIZE)) {
|
||||
|
||||
/* The record is so big that we have to store some fields
|
||||
|
|
@ -1027,7 +1031,7 @@ calculate_sizes_again:
|
|||
|
||||
*rec = page_cur_insert_rec_low(page_cursor, entry, index,
|
||||
NULL, NULL, mtr);
|
||||
if (!(*rec)) {
|
||||
if (UNIV_UNLIKELY(!(*rec))) {
|
||||
/* If the record did not fit, reorganize */
|
||||
btr_page_reorganize(page, index, mtr);
|
||||
|
||||
|
|
@ -1039,7 +1043,7 @@ calculate_sizes_again:
|
|||
|
||||
*rec = page_cur_tuple_insert(page_cursor, entry, index, mtr);
|
||||
|
||||
if (!*rec) {
|
||||
if (UNIV_UNLIKELY(!*rec)) {
|
||||
fputs("InnoDB: Error: cannot insert tuple ", stderr);
|
||||
dtuple_print(stderr, entry);
|
||||
fputs(" into ", stderr);
|
||||
|
|
@ -1166,7 +1170,7 @@ btr_cur_pessimistic_insert(
|
|||
}
|
||||
|
||||
if (rec_get_converted_size(index, entry) >=
|
||||
ut_min(page_get_free_space_of_empty(index->table->comp) / 2,
|
||||
ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,
|
||||
REC_MAX_DATA_SIZE)) {
|
||||
|
||||
/* The record is so big that we have to store some fields
|
||||
|
|
@ -1261,7 +1265,7 @@ btr_cur_upd_lock_and_undo(
|
|||
err = lock_clust_rec_modify_check_and_lock(flags, rec, index,
|
||||
rec_get_offsets(rec, index, offsets_,
|
||||
ULINT_UNDEFINED, &heap), thr);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
if (err != DB_SUCCESS) {
|
||||
|
|
@ -1293,9 +1297,11 @@ btr_cur_update_in_place_log(
|
|||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
byte* log_ptr;
|
||||
page_t* page = ut_align_down(rec, UNIV_PAGE_SIZE);
|
||||
ut_ad(flags < 256);
|
||||
ut_ad(!!page_is_comp(page) == index->table->comp);
|
||||
|
||||
log_ptr = mlog_open_and_write_index(mtr, rec, index, index->table->comp
|
||||
log_ptr = mlog_open_and_write_index(mtr, rec, index, page_is_comp(page)
|
||||
? MLOG_COMP_REC_UPDATE_IN_PLACE
|
||||
: MLOG_REC_UPDATE_IN_PLACE,
|
||||
1 + DATA_ROLL_PTR_LEN + 14 + 2 + MLOG_BUF_MARGIN);
|
||||
|
|
@ -1317,7 +1323,7 @@ btr_cur_update_in_place_log(
|
|||
|
||||
log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
|
||||
mtr);
|
||||
mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
|
||||
mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
|
||||
log_ptr += 2;
|
||||
|
||||
row_upd_index_write_log(update, log_ptr, mtr);
|
||||
|
|
@ -1374,18 +1380,12 @@ btr_cur_parse_update_in_place(
|
|||
|
||||
ptr = row_upd_index_parse(ptr, end_ptr, heap, &update);
|
||||
|
||||
if (ptr == NULL) {
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(NULL);
|
||||
if (!ptr || !page) {
|
||||
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
if (!page) {
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
ut_a(!!page_is_comp(page) == index->table->comp);
|
||||
rec = page + rec_offset;
|
||||
|
||||
/* We do not need to reserve btr_search_latch, as the page is only
|
||||
|
|
@ -1400,6 +1400,7 @@ btr_cur_parse_update_in_place(
|
|||
|
||||
row_upd_rec_in_place(rec, offsets, update);
|
||||
|
||||
func_exit:
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(ptr);
|
||||
|
|
@ -1429,7 +1430,7 @@ btr_cur_update_in_place(
|
|||
rec_t* rec;
|
||||
dulint roll_ptr = ut_dulint_zero;
|
||||
trx_t* trx;
|
||||
ibool was_delete_marked;
|
||||
ulint was_delete_marked;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
|
|
@ -1437,27 +1438,30 @@ btr_cur_update_in_place(
|
|||
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
index = cursor->index;
|
||||
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
|
||||
trx = thr_get_trx(thr);
|
||||
heap = mem_heap_create(100);
|
||||
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (btr_cur_print_record_ops && thr) {
|
||||
btr_cur_trx_report(trx, index, "update ");
|
||||
rec_print_new(stderr, rec, offsets);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/* Do lock checking and undo logging */
|
||||
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
|
||||
thr, &roll_ptr);
|
||||
if (err != DB_SUCCESS) {
|
||||
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(err);
|
||||
}
|
||||
|
||||
block = buf_block_align(rec);
|
||||
ut_ad(!!page_is_comp(buf_block_get_frame(block))
|
||||
== index->table->comp);
|
||||
|
||||
if (block->is_hashed) {
|
||||
/* The function row_upd_changes_ord_field_binary works only
|
||||
|
|
@ -1481,7 +1485,8 @@ btr_cur_update_in_place(
|
|||
/* FIXME: in a mixed tree, all records may not have enough ordering
|
||||
fields for btr search: */
|
||||
|
||||
was_delete_marked = rec_get_deleted_flag(rec, index->table->comp);
|
||||
was_delete_marked = rec_get_deleted_flag(rec,
|
||||
page_is_comp(buf_block_get_frame(block)));
|
||||
|
||||
row_upd_rec_in_place(rec, offsets, update);
|
||||
|
||||
|
|
@ -1491,14 +1496,15 @@ btr_cur_update_in_place(
|
|||
|
||||
btr_cur_update_in_place_log(flags, rec, index, update, trx, roll_ptr,
|
||||
mtr);
|
||||
if (was_delete_marked && !rec_get_deleted_flag(rec, index->table->comp)) {
|
||||
if (was_delete_marked && !rec_get_deleted_flag(rec,
|
||||
page_is_comp(buf_block_get_frame(block)))) {
|
||||
/* The new updated record owns its possible externally
|
||||
stored fields */
|
||||
|
||||
btr_cur_unmark_extern_fields(rec, mtr, offsets);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(DB_SUCCESS);
|
||||
|
|
@ -1547,14 +1553,17 @@ btr_cur_optimistic_update(
|
|||
page = btr_cur_get_page(cursor);
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
index = cursor->index;
|
||||
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
|
||||
|
||||
heap = mem_heap_create(1024);
|
||||
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (btr_cur_print_record_ops && thr) {
|
||||
btr_cur_trx_report(thr_get_trx(thr), index, "update ");
|
||||
rec_print_new(stderr, rec, offsets);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
|
||||
MTR_MEMO_PAGE_X_FIX));
|
||||
|
|
@ -1596,8 +1605,8 @@ btr_cur_optimistic_update(
|
|||
old_rec_size = rec_offs_size(offsets);
|
||||
new_rec_size = rec_get_converted_size(index, new_entry);
|
||||
|
||||
if (new_rec_size >=
|
||||
page_get_free_space_of_empty(index->table->comp) / 2) {
|
||||
if (UNIV_UNLIKELY(new_rec_size >= page_get_free_space_of_empty(
|
||||
page_is_comp(page)) / 2)) {
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
|
|
@ -1607,8 +1616,9 @@ btr_cur_optimistic_update(
|
|||
max_size = old_rec_size
|
||||
+ page_get_max_insert_size_after_reorganize(page, 1);
|
||||
|
||||
if (page_get_data_size(page) - old_rec_size + new_rec_size
|
||||
< BTR_CUR_PAGE_COMPRESS_LIMIT) {
|
||||
if (UNIV_UNLIKELY(page_get_data_size(page)
|
||||
- old_rec_size + new_rec_size
|
||||
< BTR_CUR_PAGE_COMPRESS_LIMIT)) {
|
||||
|
||||
/* The page would become too empty */
|
||||
|
||||
|
|
@ -1644,7 +1654,7 @@ btr_cur_optimistic_update(
|
|||
explicit locks on rec, before deleting rec (see the comment in
|
||||
.._pessimistic_update). */
|
||||
|
||||
lock_rec_store_on_page_infimum(rec);
|
||||
lock_rec_store_on_page_infimum(page, rec);
|
||||
|
||||
btr_search_update_hash_on_delete(cursor);
|
||||
|
||||
|
|
@ -1665,7 +1675,7 @@ btr_cur_optimistic_update(
|
|||
|
||||
ut_a(rec); /* <- We calculated above the insert would fit */
|
||||
|
||||
if (!rec_get_deleted_flag(rec, index->table->comp)) {
|
||||
if (!rec_get_deleted_flag(rec, page_is_comp(page))) {
|
||||
/* The new inserted record owns its possible externally
|
||||
stored fields */
|
||||
|
||||
|
|
@ -1814,7 +1824,7 @@ btr_cur_pessimistic_update(
|
|||
}
|
||||
|
||||
success = fsp_reserve_free_extents(&n_reserved,
|
||||
cursor->index->space,
|
||||
index->space,
|
||||
n_extents, reserve_flag, mtr);
|
||||
if (!success) {
|
||||
err = DB_OUT_OF_FILE_SPACE;
|
||||
|
|
@ -1858,14 +1868,14 @@ btr_cur_pessimistic_update(
|
|||
|
||||
ext_vect = mem_heap_alloc(heap, sizeof(ulint)
|
||||
* dict_index_get_n_fields(index));
|
||||
ut_ad(!cursor->index->table->comp || !rec_get_node_ptr_flag(rec));
|
||||
ut_ad(!page_is_comp(page) || !rec_get_node_ptr_flag(rec));
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
n_ext_vect = btr_push_update_extern_fields(ext_vect, offsets, update);
|
||||
|
||||
if (rec_get_converted_size(index, new_entry) >=
|
||||
ut_min(page_get_free_space_of_empty(index->table->comp) / 2,
|
||||
REC_MAX_DATA_SIZE)) {
|
||||
if (UNIV_UNLIKELY(rec_get_converted_size(index, new_entry) >=
|
||||
ut_min(page_get_free_space_of_empty(page_is_comp(page)) / 2,
|
||||
REC_MAX_DATA_SIZE))) {
|
||||
|
||||
big_rec_vec = dtuple_convert_big_rec(index, new_entry,
|
||||
ext_vect, n_ext_vect);
|
||||
|
|
@ -1887,7 +1897,7 @@ btr_cur_pessimistic_update(
|
|||
delete the lock structs set on the root page even if the root
|
||||
page carries just node pointers. */
|
||||
|
||||
lock_rec_store_on_page_infimum(rec);
|
||||
lock_rec_store_on_page_infimum(buf_frame_align(rec), rec);
|
||||
|
||||
btr_search_update_hash_on_delete(cursor);
|
||||
|
||||
|
|
@ -1965,8 +1975,7 @@ return_after_reservations:
|
|||
mem_heap_free(heap);
|
||||
|
||||
if (n_extents > 0) {
|
||||
fil_space_release_free_extents(cursor->index->space,
|
||||
n_reserved);
|
||||
fil_space_release_free_extents(index->space, n_reserved);
|
||||
}
|
||||
|
||||
*big_rec = big_rec_vec;
|
||||
|
|
@ -1995,7 +2004,10 @@ btr_cur_del_mark_set_clust_rec_log(
|
|||
ut_ad(flags < 256);
|
||||
ut_ad(val <= 1);
|
||||
|
||||
log_ptr = mlog_open_and_write_index(mtr, rec, index, index->table->comp
|
||||
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
|
||||
|
||||
log_ptr = mlog_open_and_write_index(mtr, rec, index,
|
||||
page_rec_is_comp(rec)
|
||||
? MLOG_COMP_REC_CLUST_DELETE_MARK
|
||||
: MLOG_REC_CLUST_DELETE_MARK,
|
||||
1 + 1 + DATA_ROLL_PTR_LEN + 14 + 2);
|
||||
|
|
@ -2012,7 +2024,7 @@ btr_cur_del_mark_set_clust_rec_log(
|
|||
|
||||
log_ptr = row_upd_write_sys_vals_to_log(index, trx, roll_ptr, log_ptr,
|
||||
mtr);
|
||||
mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
|
||||
mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
|
||||
log_ptr += 2;
|
||||
|
||||
mlog_close(mtr, log_ptr);
|
||||
|
|
@ -2032,13 +2044,15 @@ btr_cur_parse_del_mark_set_clust_rec(
|
|||
page_t* page) /* in: page or NULL */
|
||||
{
|
||||
ulint flags;
|
||||
ibool val;
|
||||
ulint val;
|
||||
ulint pos;
|
||||
dulint trx_id;
|
||||
dulint roll_ptr;
|
||||
ulint offset;
|
||||
rec_t* rec;
|
||||
|
||||
ut_ad(!page || !!page_is_comp(page) == index->table->comp);
|
||||
|
||||
if (end_ptr < ptr + 2) {
|
||||
|
||||
return(NULL);
|
||||
|
|
@ -2078,7 +2092,7 @@ btr_cur_parse_del_mark_set_clust_rec(
|
|||
rec_get_offsets(rec, index, offsets_,
|
||||
ULINT_UNDEFINED, &heap),
|
||||
pos, trx_id, roll_ptr);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
|
@ -2087,7 +2101,7 @@ btr_cur_parse_del_mark_set_clust_rec(
|
|||
is only being recovered, and there cannot be a hash index to
|
||||
it. */
|
||||
|
||||
rec_set_deleted_flag(rec, index->table->comp, val);
|
||||
rec_set_deleted_flag(rec, page_is_comp(page), val);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
|
@ -2123,22 +2137,25 @@ btr_cur_del_mark_set_clust_rec(
|
|||
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
index = cursor->index;
|
||||
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
|
||||
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (btr_cur_print_record_ops && thr) {
|
||||
btr_cur_trx_report(thr_get_trx(thr), index, "del mark ");
|
||||
rec_print_new(stderr, rec, offsets);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ut_ad(index->type & DICT_CLUSTERED);
|
||||
ut_ad(rec_get_deleted_flag(rec, index->table->comp) == FALSE);
|
||||
ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
|
||||
|
||||
err = lock_clust_rec_modify_check_and_lock(flags,
|
||||
rec, index, offsets, thr);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(err);
|
||||
|
|
@ -2149,7 +2166,7 @@ btr_cur_del_mark_set_clust_rec(
|
|||
&roll_ptr);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(err);
|
||||
|
|
@ -2161,7 +2178,7 @@ btr_cur_del_mark_set_clust_rec(
|
|||
rw_lock_x_lock(&btr_search_latch);
|
||||
}
|
||||
|
||||
rec_set_deleted_flag(rec, index->table->comp, val);
|
||||
rec_set_deleted_flag(rec, rec_offs_comp(offsets), val);
|
||||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
|
|
@ -2175,7 +2192,7 @@ btr_cur_del_mark_set_clust_rec(
|
|||
|
||||
btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
|
||||
roll_ptr, mtr);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(DB_SUCCESS);
|
||||
|
|
@ -2189,17 +2206,13 @@ void
|
|||
btr_cur_del_mark_set_sec_rec_log(
|
||||
/*=============================*/
|
||||
rec_t* rec, /* in: record */
|
||||
dict_index_t* index, /* in: record descriptor */
|
||||
ibool val, /* in: value to set */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
byte* log_ptr;
|
||||
ut_ad(val <= 1);
|
||||
|
||||
log_ptr = mlog_open_and_write_index(mtr, rec, index, index->table->comp
|
||||
? MLOG_COMP_REC_SEC_DELETE_MARK
|
||||
: MLOG_REC_SEC_DELETE_MARK,
|
||||
1 + 2);
|
||||
log_ptr = mlog_open(mtr, 11 + 1 + 2);
|
||||
|
||||
if (!log_ptr) {
|
||||
/* Logging in mtr is switched off during crash recovery:
|
||||
|
|
@ -2207,10 +2220,12 @@ btr_cur_del_mark_set_sec_rec_log(
|
|||
return;
|
||||
}
|
||||
|
||||
log_ptr = mlog_write_initial_log_record_fast(
|
||||
rec, MLOG_REC_SEC_DELETE_MARK, log_ptr, mtr);
|
||||
mach_write_to_1(log_ptr, val);
|
||||
log_ptr++;
|
||||
|
||||
mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
|
||||
mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
|
||||
log_ptr += 2;
|
||||
|
||||
mlog_close(mtr, log_ptr);
|
||||
|
|
@ -2226,10 +2241,9 @@ btr_cur_parse_del_mark_set_sec_rec(
|
|||
/* out: end of log record or NULL */
|
||||
byte* ptr, /* in: buffer */
|
||||
byte* end_ptr,/* in: buffer end */
|
||||
dict_index_t* index, /* in: record descriptor */
|
||||
page_t* page) /* in: page or NULL */
|
||||
{
|
||||
ibool val;
|
||||
ulint val;
|
||||
ulint offset;
|
||||
rec_t* rec;
|
||||
|
||||
|
|
@ -2253,7 +2267,7 @@ btr_cur_parse_del_mark_set_sec_rec(
|
|||
is only being recovered, and there cannot be a hash index to
|
||||
it. */
|
||||
|
||||
rec_set_deleted_flag(rec, index->table->comp, val);
|
||||
rec_set_deleted_flag(rec, page_is_comp(page), val);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
|
@ -2279,11 +2293,13 @@ btr_cur_del_mark_set_sec_rec(
|
|||
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (btr_cur_print_record_ops && thr) {
|
||||
btr_cur_trx_report(thr_get_trx(thr), cursor->index,
|
||||
"del mark ");
|
||||
rec_print(stderr, rec, cursor->index);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
err = lock_sec_rec_modify_check_and_lock(flags, rec, cursor->index,
|
||||
thr);
|
||||
|
|
@ -2293,18 +2309,21 @@ btr_cur_del_mark_set_sec_rec(
|
|||
}
|
||||
|
||||
block = buf_block_align(rec);
|
||||
ut_ad(!!page_is_comp(buf_block_get_frame(block))
|
||||
== cursor->index->table->comp);
|
||||
|
||||
if (block->is_hashed) {
|
||||
rw_lock_x_lock(&btr_search_latch);
|
||||
}
|
||||
|
||||
rec_set_deleted_flag(rec, cursor->index->table->comp, val);
|
||||
rec_set_deleted_flag(rec, page_is_comp(buf_block_get_frame(block)),
|
||||
val);
|
||||
|
||||
if (block->is_hashed) {
|
||||
rw_lock_x_unlock(&btr_search_latch);
|
||||
}
|
||||
|
||||
btr_cur_del_mark_set_sec_rec_log(rec, cursor->index, val, mtr);
|
||||
btr_cur_del_mark_set_sec_rec_log(rec, val, mtr);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
|
@ -2317,15 +2336,14 @@ void
|
|||
btr_cur_del_unmark_for_ibuf(
|
||||
/*========================*/
|
||||
rec_t* rec, /* in: record to delete unmark */
|
||||
dict_index_t* index, /* in: record descriptor */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
/* We do not need to reserve btr_search_latch, as the page has just
|
||||
been read to the buffer pool and there cannot be a hash index to it. */
|
||||
|
||||
rec_set_deleted_flag(rec, index->table->comp, FALSE);
|
||||
rec_set_deleted_flag(rec, page_is_comp(buf_frame_align(rec)), FALSE);
|
||||
|
||||
btr_cur_del_mark_set_sec_rec_log(rec, index, FALSE, mtr);
|
||||
btr_cur_del_mark_set_sec_rec_log(rec, FALSE, mtr);
|
||||
}
|
||||
|
||||
/*==================== B-TREE RECORD REMOVE =========================*/
|
||||
|
|
@ -2444,7 +2462,7 @@ btr_cur_optimistic_delete(
|
|||
mtr);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
|
|
@ -2487,6 +2505,7 @@ btr_cur_pessimistic_delete(
|
|||
ulint n_reserved;
|
||||
ibool success;
|
||||
ibool ret = FALSE;
|
||||
ulint level;
|
||||
mem_heap_t* heap;
|
||||
ulint* offsets;
|
||||
|
||||
|
|
@ -2523,15 +2542,15 @@ btr_cur_pessimistic_delete(
|
|||
/* Free externally stored fields if the record is neither
|
||||
a node pointer nor in two-byte format.
|
||||
This avoids an unnecessary loop. */
|
||||
if (cursor->index->table->comp
|
||||
if (page_is_comp(page)
|
||||
? !rec_get_node_ptr_flag(rec)
|
||||
: !rec_get_1byte_offs_flag(rec)) {
|
||||
btr_rec_free_externally_stored_fields(cursor->index,
|
||||
rec, offsets, in_rollback, mtr);
|
||||
}
|
||||
|
||||
if ((page_get_n_recs(page) < 2)
|
||||
&& (dict_tree_get_page(btr_cur_get_tree(cursor))
|
||||
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
|
||||
&& UNIV_UNLIKELY(dict_tree_get_page(btr_cur_get_tree(cursor))
|
||||
!= buf_frame_get_page_no(page))) {
|
||||
|
||||
/* If there is only one record, drop the whole page in
|
||||
|
|
@ -2546,9 +2565,13 @@ btr_cur_pessimistic_delete(
|
|||
}
|
||||
|
||||
lock_update_delete(rec);
|
||||
level = btr_page_get_level(page, mtr);
|
||||
|
||||
if ((btr_page_get_level(page, mtr) > 0)
|
||||
&& (page_rec_get_next(page_get_infimum_rec(page)) == rec)) {
|
||||
if (level > 0
|
||||
&& UNIV_UNLIKELY(rec == page_rec_get_next(
|
||||
page_get_infimum_rec(page)))) {
|
||||
|
||||
rec_t* next_rec = page_rec_get_next(rec);
|
||||
|
||||
if (btr_page_get_prev(page, mtr) == FIL_NULL) {
|
||||
|
||||
|
|
@ -2556,8 +2579,8 @@ btr_cur_pessimistic_delete(
|
|||
non-leaf level, we must mark the new leftmost node
|
||||
pointer as the predefined minimum record */
|
||||
|
||||
btr_set_min_rec_mark(page_rec_get_next(rec),
|
||||
cursor->index->table->comp, mtr);
|
||||
btr_set_min_rec_mark(next_rec, page_is_comp(page),
|
||||
mtr);
|
||||
} else {
|
||||
/* Otherwise, if we delete the leftmost node pointer
|
||||
on a page, we have to change the father node pointer
|
||||
|
|
@ -2567,13 +2590,12 @@ btr_cur_pessimistic_delete(
|
|||
btr_node_ptr_delete(tree, page, mtr);
|
||||
|
||||
node_ptr = dict_tree_build_node_ptr(
|
||||
tree, page_rec_get_next(rec),
|
||||
tree, next_rec,
|
||||
buf_frame_get_page_no(page),
|
||||
heap, btr_page_get_level(page, mtr));
|
||||
heap, level);
|
||||
|
||||
btr_insert_on_non_leaf_level(tree,
|
||||
btr_page_get_level(page, mtr) + 1,
|
||||
node_ptr, mtr);
|
||||
level + 1, node_ptr, mtr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2813,12 +2835,13 @@ btr_estimate_number_of_different_key_vals(
|
|||
ulint add_on;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets1_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint offsets2_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets1 = offsets1_;
|
||||
ulint* offsets2 = offsets2_;
|
||||
*offsets1_ = (sizeof offsets1_) / sizeof *offsets1_;
|
||||
*offsets2_ = (sizeof offsets2_) / sizeof *offsets2_;
|
||||
ulint offsets_rec_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint offsets_next_rec_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets_rec = offsets_rec_;
|
||||
ulint* offsets_next_rec= offsets_next_rec_;
|
||||
*offsets_rec_ = (sizeof offsets_rec_) / sizeof *offsets_rec_;
|
||||
*offsets_next_rec_ =
|
||||
(sizeof offsets_next_rec_) / sizeof *offsets_next_rec_;
|
||||
|
||||
n_cols = dict_index_get_n_unique(index);
|
||||
|
||||
|
|
@ -2831,6 +2854,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
/* We sample some pages in the index to get an estimate */
|
||||
|
||||
for (i = 0; i < BTR_KEY_VAL_ESTIMATE_N_PAGES; i++) {
|
||||
rec_t* supremum;
|
||||
mtr_start(&mtr);
|
||||
|
||||
btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
|
||||
|
|
@ -2843,26 +2867,29 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
page = btr_cur_get_page(&cursor);
|
||||
|
||||
rec = page_get_infimum_rec(page);
|
||||
rec = page_rec_get_next(rec);
|
||||
supremum = page_get_supremum_rec(page);
|
||||
rec = page_rec_get_next(page_get_infimum_rec(page));
|
||||
|
||||
if (rec != page_get_supremum_rec(page)) {
|
||||
if (rec != supremum) {
|
||||
not_empty_flag = 1;
|
||||
offsets_rec = rec_get_offsets(rec, index, offsets_rec,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
}
|
||||
|
||||
while (rec != page_get_supremum_rec(page)
|
||||
&& page_rec_get_next(rec)
|
||||
!= page_get_supremum_rec(page)) {
|
||||
|
||||
while (rec != supremum) {
|
||||
rec_t* next_rec = page_rec_get_next(rec);
|
||||
if (next_rec == supremum) {
|
||||
break;
|
||||
}
|
||||
|
||||
matched_fields = 0;
|
||||
matched_bytes = 0;
|
||||
offsets1 = rec_get_offsets(rec, index, offsets1,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
offsets2 = rec_get_offsets(next_rec, index, offsets2,
|
||||
offsets_next_rec = rec_get_offsets(next_rec, index,
|
||||
offsets_next_rec,
|
||||
n_cols, &heap);
|
||||
|
||||
cmp_rec_rec_with_match(rec, next_rec,
|
||||
offsets1, offsets2,
|
||||
offsets_rec, offsets_next_rec,
|
||||
index, &matched_fields,
|
||||
&matched_bytes);
|
||||
|
||||
|
|
@ -2875,9 +2902,17 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
total_external_size +=
|
||||
btr_rec_get_externally_stored_len(
|
||||
rec, offsets1);
|
||||
rec, offsets_rec);
|
||||
|
||||
rec = page_rec_get_next(rec);
|
||||
rec = next_rec;
|
||||
/* Initialize offsets_rec for the next round
|
||||
and assign the old offsets_rec buffer to
|
||||
offsets_next_rec. */
|
||||
{
|
||||
ulint* offsets_tmp = offsets_rec;
|
||||
offsets_rec = offsets_next_rec;
|
||||
offsets_next_rec = offsets_tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2899,11 +2934,11 @@ btr_estimate_number_of_different_key_vals(
|
|||
}
|
||||
}
|
||||
|
||||
offsets1 = rec_get_offsets(rec, index, offsets1,
|
||||
offsets_rec = rec_get_offsets(rec, index, offsets_rec,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
total_external_size +=
|
||||
btr_rec_get_externally_stored_len(rec,
|
||||
offsets1);
|
||||
offsets_rec);
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
|
|
@ -2944,7 +2979,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
}
|
||||
|
||||
mem_free(n_diff);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
|
@ -3599,7 +3634,7 @@ btr_rec_free_externally_stored_fields(
|
|||
MTR_MEMO_PAGE_X_FIX));
|
||||
/* Free possible externally stored fields in the record */
|
||||
|
||||
ut_ad(index->table->comp == rec_offs_comp(offsets));
|
||||
ut_ad(index->table->comp == !!rec_offs_comp(offsets));
|
||||
n_fields = rec_offs_n_fields(offsets);
|
||||
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ btr_pcur_store_position(
|
|||
rec_t* rec;
|
||||
dict_tree_t* tree;
|
||||
page_t* page;
|
||||
ulint offs;
|
||||
|
||||
ut_a(cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||
ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
|
||||
|
|
@ -87,7 +88,8 @@ btr_pcur_store_position(
|
|||
page_cursor = btr_pcur_get_page_cur(cursor);
|
||||
|
||||
rec = page_cur_get_rec(page_cursor);
|
||||
page = buf_frame_align(rec);
|
||||
page = ut_align_down(rec, UNIV_PAGE_SIZE);
|
||||
offs = ut_align_offset(rec, UNIV_PAGE_SIZE);
|
||||
|
||||
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
|
||||
MTR_MEMO_PAGE_S_FIX)
|
||||
|
|
@ -95,35 +97,33 @@ btr_pcur_store_position(
|
|||
MTR_MEMO_PAGE_X_FIX));
|
||||
ut_a(cursor->latch_mode != BTR_NO_LATCHES);
|
||||
|
||||
if (page_get_n_recs(page) == 0) {
|
||||
if (UNIV_UNLIKELY(page_get_n_recs(page) == 0)) {
|
||||
/* It must be an empty index tree; NOTE that in this case
|
||||
we do not store the modify_clock, but always do a search
|
||||
if we restore the cursor position */
|
||||
|
||||
ut_a(btr_page_get_next(page, mtr) == FIL_NULL
|
||||
&& btr_page_get_prev(page, mtr) == FIL_NULL);
|
||||
ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
|
||||
ut_a(btr_page_get_prev(page, mtr) == FIL_NULL);
|
||||
|
||||
if (rec == page_get_supremum_rec(page)) {
|
||||
cursor->old_stored = BTR_PCUR_OLD_STORED;
|
||||
|
||||
if (page_rec_is_supremum_low(offs)) {
|
||||
|
||||
cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
|
||||
cursor->old_stored = BTR_PCUR_OLD_STORED;
|
||||
|
||||
return;
|
||||
} else {
|
||||
cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE;
|
||||
}
|
||||
|
||||
cursor->rel_pos = BTR_PCUR_BEFORE_FIRST_IN_TREE;
|
||||
cursor->old_stored = BTR_PCUR_OLD_STORED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (rec == page_get_supremum_rec(page)) {
|
||||
if (page_rec_is_supremum_low(offs)) {
|
||||
|
||||
rec = page_rec_get_prev(rec);
|
||||
|
||||
cursor->rel_pos = BTR_PCUR_AFTER;
|
||||
|
||||
} else if (rec == page_get_infimum_rec(page)) {
|
||||
} else if (page_rec_is_infimum_low(offs)) {
|
||||
|
||||
rec = page_rec_get_next(rec);
|
||||
|
||||
|
|
@ -139,7 +139,8 @@ btr_pcur_store_position(
|
|||
&cursor->buf_size);
|
||||
|
||||
cursor->block_when_stored = buf_block_align(page);
|
||||
cursor->modify_clock = buf_frame_get_modify_clock(page);
|
||||
cursor->modify_clock = buf_block_get_modify_clock(
|
||||
cursor->block_when_stored);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
@ -202,33 +203,27 @@ btr_pcur_restore_position(
|
|||
dtuple_t* tuple;
|
||||
ulint mode;
|
||||
ulint old_mode;
|
||||
ibool from_left;
|
||||
mem_heap_t* heap;
|
||||
|
||||
ut_a(cursor->pos_state == BTR_PCUR_WAS_POSITIONED
|
||||
|| cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||
if (cursor->old_stored != BTR_PCUR_OLD_STORED) {
|
||||
if (UNIV_UNLIKELY(cursor->old_stored != BTR_PCUR_OLD_STORED)
|
||||
|| UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
|
||||
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
|
||||
ut_print_buf(stderr, (const byte*)cursor, sizeof(btr_pcur_t));
|
||||
if (cursor->trx_if_known) {
|
||||
trx_print(stderr, cursor->trx_if_known);
|
||||
}
|
||||
|
||||
ut_a(0);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
if (cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
|
||||
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
|
||||
if (UNIV_UNLIKELY(cursor->rel_pos == BTR_PCUR_AFTER_LAST_IN_TREE
|
||||
|| cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE)) {
|
||||
|
||||
/* In these cases we do not try an optimistic restoration,
|
||||
but always do a search */
|
||||
|
||||
if (cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
|
||||
from_left = TRUE;
|
||||
} else {
|
||||
from_left = FALSE;
|
||||
}
|
||||
|
||||
btr_cur_open_at_index_side(from_left,
|
||||
btr_cur_open_at_index_side(
|
||||
cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
|
||||
btr_pcur_get_btr_cur(cursor)->index, latch_mode,
|
||||
btr_pcur_get_btr_cur(cursor), mtr);
|
||||
|
||||
|
|
@ -243,12 +238,13 @@ btr_pcur_restore_position(
|
|||
|
||||
page = btr_cur_get_page(btr_pcur_get_btr_cur(cursor));
|
||||
|
||||
if (latch_mode == BTR_SEARCH_LEAF || latch_mode == BTR_MODIFY_LEAF) {
|
||||
if (UNIV_LIKELY(latch_mode == BTR_SEARCH_LEAF)
|
||||
|| UNIV_LIKELY(latch_mode == BTR_MODIFY_LEAF)) {
|
||||
/* Try optimistic restoration */
|
||||
|
||||
if (buf_page_optimistic_get(latch_mode,
|
||||
if (UNIV_LIKELY(buf_page_optimistic_get(latch_mode,
|
||||
cursor->block_when_stored, page,
|
||||
cursor->modify_clock, mtr)) {
|
||||
cursor->modify_clock, mtr))) {
|
||||
cursor->pos_state = BTR_PCUR_IS_POSITIONED;
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
|
||||
|
|
@ -297,7 +293,7 @@ btr_pcur_restore_position(
|
|||
/* Save the old search mode of the cursor */
|
||||
old_mode = cursor->search_mode;
|
||||
|
||||
if (cursor->rel_pos == BTR_PCUR_ON) {
|
||||
if (UNIV_LIKELY(cursor->rel_pos == BTR_PCUR_ON)) {
|
||||
mode = PAGE_CUR_LE;
|
||||
} else if (cursor->rel_pos == BTR_PCUR_AFTER) {
|
||||
mode = PAGE_CUR_G;
|
||||
|
|
@ -323,12 +319,10 @@ btr_pcur_restore_position(
|
|||
the cursor can now be on a different page! But we can retain
|
||||
the value of old_rec */
|
||||
|
||||
cursor->modify_clock =
|
||||
buf_frame_get_modify_clock(btr_pcur_get_page(cursor));
|
||||
|
||||
cursor->block_when_stored =
|
||||
buf_block_align(btr_pcur_get_page(cursor));
|
||||
|
||||
cursor->modify_clock =
|
||||
buf_block_get_modify_clock(cursor->block_when_stored);
|
||||
cursor->old_stored = BTR_PCUR_OLD_STORED;
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ btr_search_update_hash_ref(
|
|||
offsets_, ULINT_UNDEFINED, &heap),
|
||||
block->curr_n_fields,
|
||||
block->curr_n_bytes, tree_id);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
|
@ -544,10 +544,7 @@ btr_search_check_guess(
|
|||
or PAGE_CUR_GE */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
page_t* page;
|
||||
rec_t* rec;
|
||||
rec_t* prev_rec;
|
||||
rec_t* next_rec;
|
||||
ulint n_unique;
|
||||
ulint match;
|
||||
ulint bytes;
|
||||
|
|
@ -561,7 +558,6 @@ btr_search_check_guess(
|
|||
n_unique = dict_index_get_n_unique_in_tree(cursor->index);
|
||||
|
||||
rec = btr_cur_get_rec(cursor);
|
||||
page = buf_frame_align(rec);
|
||||
|
||||
ut_ad(page_rec_is_user_rec(rec));
|
||||
|
||||
|
|
@ -611,13 +607,16 @@ btr_search_check_guess(
|
|||
bytes = 0;
|
||||
|
||||
if ((mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)) {
|
||||
rec_t* prev_rec;
|
||||
|
||||
ut_ad(rec != page_get_infimum_rec(page));
|
||||
ut_ad(!page_rec_is_infimum(rec));
|
||||
|
||||
prev_rec = page_rec_get_prev(rec);
|
||||
|
||||
if (prev_rec == page_get_infimum_rec(page)) {
|
||||
success = btr_page_get_prev(page, mtr) == FIL_NULL;
|
||||
if (page_rec_is_infimum(prev_rec)) {
|
||||
success = btr_page_get_prev(
|
||||
buf_frame_align(prev_rec), mtr) == FIL_NULL;
|
||||
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
|
|
@ -632,34 +631,37 @@ btr_search_check_guess(
|
|||
}
|
||||
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
ut_ad(rec != page_get_supremum_rec(page));
|
||||
} else {
|
||||
rec_t* next_rec;
|
||||
|
||||
ut_ad(!page_rec_is_supremum(rec));
|
||||
|
||||
next_rec = page_rec_get_next(rec);
|
||||
next_rec = page_rec_get_next(rec);
|
||||
|
||||
if (next_rec == page_get_supremum_rec(page)) {
|
||||
if (btr_page_get_next(page, mtr) == FIL_NULL) {
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
if (btr_page_get_next(
|
||||
buf_frame_align(next_rec), mtr) == FIL_NULL) {
|
||||
|
||||
cursor->up_match = 0;
|
||||
success = TRUE;
|
||||
cursor->up_match = 0;
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
goto exit_func;
|
||||
}
|
||||
|
||||
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
|
||||
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
|
||||
n_unique, &heap);
|
||||
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec,
|
||||
offsets, &match, &bytes);
|
||||
if (mode == PAGE_CUR_LE) {
|
||||
success = cmp == -1;
|
||||
cursor->up_match = match;
|
||||
} else {
|
||||
success = cmp != 1;
|
||||
cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec,
|
||||
offsets, &match, &bytes);
|
||||
if (mode == PAGE_CUR_LE) {
|
||||
success = cmp == -1;
|
||||
cursor->up_match = match;
|
||||
} else {
|
||||
success = cmp != 1;
|
||||
}
|
||||
}
|
||||
exit_func:
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
return(success);
|
||||
|
|
@ -694,7 +696,6 @@ btr_search_guess_on_hash(
|
|||
buf_block_t* block;
|
||||
rec_t* rec;
|
||||
page_t* page;
|
||||
ibool success;
|
||||
ulint fold;
|
||||
ulint tuple_n_fields;
|
||||
dulint tree_id;
|
||||
|
|
@ -710,7 +711,7 @@ btr_search_guess_on_hash(
|
|||
/* Note that, for efficiency, the struct info may not be protected by
|
||||
any latch here! */
|
||||
|
||||
if (info->n_hash_potential == 0) {
|
||||
if (UNIV_UNLIKELY(info->n_hash_potential == 0)) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
|
@ -720,12 +721,13 @@ btr_search_guess_on_hash(
|
|||
|
||||
tuple_n_fields = dtuple_get_n_fields(tuple);
|
||||
|
||||
if (tuple_n_fields < cursor->n_fields) {
|
||||
if (UNIV_UNLIKELY(tuple_n_fields < cursor->n_fields)) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if ((cursor->n_bytes > 0) && (tuple_n_fields <= cursor->n_fields)) {
|
||||
if (UNIV_UNLIKELY(tuple_n_fields == cursor->n_fields)
|
||||
&& (cursor->n_bytes > 0)) {
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
|
@ -740,39 +742,31 @@ btr_search_guess_on_hash(
|
|||
cursor->fold = fold;
|
||||
cursor->flag = BTR_CUR_HASH;
|
||||
|
||||
if (!has_search_latch) {
|
||||
if (UNIV_LIKELY(!has_search_latch)) {
|
||||
rw_lock_s_lock(&btr_search_latch);
|
||||
}
|
||||
|
||||
ut_a(btr_search_latch.writer != RW_LOCK_EX);
|
||||
ut_a(btr_search_latch.reader_count > 0);
|
||||
ut_ad(btr_search_latch.writer != RW_LOCK_EX);
|
||||
ut_ad(btr_search_latch.reader_count > 0);
|
||||
|
||||
rec = ha_search_and_get_data(btr_search_sys->hash_index, fold);
|
||||
|
||||
if (!rec) {
|
||||
if (!has_search_latch) {
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
}
|
||||
|
||||
goto failure;
|
||||
if (UNIV_UNLIKELY(!rec)) {
|
||||
goto failure_unlock;
|
||||
}
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
|
||||
if (!has_search_latch) {
|
||||
if (UNIV_LIKELY(!has_search_latch)) {
|
||||
|
||||
success = buf_page_get_known_nowait(latch_mode, page,
|
||||
if (UNIV_UNLIKELY(!buf_page_get_known_nowait(latch_mode, page,
|
||||
BUF_MAKE_YOUNG,
|
||||
__FILE__, __LINE__,
|
||||
mtr);
|
||||
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
|
||||
if (!success) {
|
||||
|
||||
goto failure;
|
||||
mtr))) {
|
||||
goto failure_unlock;
|
||||
}
|
||||
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
can_only_compare_to_cursor_rec = FALSE;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
|
|
@ -782,8 +776,8 @@ btr_search_guess_on_hash(
|
|||
|
||||
block = buf_block_align(page);
|
||||
|
||||
if (block->state == BUF_BLOCK_REMOVE_HASH) {
|
||||
if (!has_search_latch) {
|
||||
if (UNIV_UNLIKELY(block->state == BUF_BLOCK_REMOVE_HASH)) {
|
||||
if (UNIV_LIKELY(!has_search_latch)) {
|
||||
|
||||
btr_leaf_page_release(page, latch_mode, mtr);
|
||||
}
|
||||
|
|
@ -791,51 +785,33 @@ btr_search_guess_on_hash(
|
|||
goto failure;
|
||||
}
|
||||
|
||||
ut_a(block->state == BUF_BLOCK_FILE_PAGE);
|
||||
ut_a(page_rec_is_user_rec(rec));
|
||||
ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(page_rec_is_user_rec(rec));
|
||||
|
||||
btr_cur_position(index, rec, cursor);
|
||||
|
||||
/* Check the validity of the guess within the page */
|
||||
|
||||
if (0 != ut_dulint_cmp(tree_id, btr_page_get_index_id(page))) {
|
||||
|
||||
success = FALSE;
|
||||
/*
|
||||
fprintf(stderr, "Tree id %lu, page index id %lu fold %lu\n",
|
||||
ut_dulint_get_low(tree_id),
|
||||
ut_dulint_get_low(btr_page_get_index_id(page)),
|
||||
fold);
|
||||
*/
|
||||
} else {
|
||||
/* If we only have the latch on btr_search_latch, not on the
|
||||
page, it only protects the columns of the record the cursor
|
||||
is positioned on. We cannot look at the next of the previous
|
||||
record to determine if our guess for the cursor position is
|
||||
right. */
|
||||
|
||||
success = btr_search_check_guess(cursor,
|
||||
can_only_compare_to_cursor_rec,
|
||||
tuple, mode, mtr);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
if (!has_search_latch) {
|
||||
/* If we only have the latch on btr_search_latch, not on the
|
||||
page, it only protects the columns of the record the cursor
|
||||
is positioned on. We cannot look at the next of the previous
|
||||
record to determine if our guess for the cursor position is
|
||||
right. */
|
||||
if (UNIV_EXPECT(ut_dulint_cmp(tree_id, btr_page_get_index_id(page)), 0)
|
||||
|| !btr_search_check_guess(cursor, can_only_compare_to_cursor_rec,
|
||||
tuple, mode, mtr)) {
|
||||
if (UNIV_LIKELY(!has_search_latch)) {
|
||||
btr_leaf_page_release(page, latch_mode, mtr);
|
||||
}
|
||||
|
||||
goto failure;
|
||||
}
|
||||
|
||||
if (info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5) {
|
||||
if (UNIV_LIKELY(info->n_hash_potential < BTR_SEARCH_BUILD_LIMIT + 5)) {
|
||||
|
||||
info->n_hash_potential++;
|
||||
}
|
||||
|
||||
if (info->last_hash_succ != TRUE) {
|
||||
info->last_hash_succ = TRUE;
|
||||
}
|
||||
|
||||
#ifdef notdefined
|
||||
/* These lines of code can be used in a debug version to check
|
||||
the correctness of the searched cursor position: */
|
||||
|
|
@ -843,15 +819,14 @@ btr_search_guess_on_hash(
|
|||
info->last_hash_succ = FALSE;
|
||||
|
||||
/* Currently, does not work if the following fails: */
|
||||
ut_a(!has_search_latch);
|
||||
ut_ad(!has_search_latch);
|
||||
|
||||
btr_leaf_page_release(page, latch_mode, mtr);
|
||||
|
||||
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)))) {
|
||||
&& page_rec_is_supremum(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
|
||||
|
|
@ -861,22 +836,22 @@ btr_search_guess_on_hash(
|
|||
|
||||
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));
|
||||
ut_ad(btr_pcur_get_rec(&pcur) == btr_cur_get_rec(cursor));
|
||||
} else {
|
||||
ut_a(btr_cur_get_rec(&cursor2) == btr_cur_get_rec(cursor));
|
||||
ut_ad(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
|
||||
info->last_hash_succ = TRUE;
|
||||
|
||||
#ifdef UNIV_SEARCH_PERF_STAT
|
||||
btr_search_n_succ++;
|
||||
#endif
|
||||
if (!has_search_latch && buf_block_peek_if_too_old(block)) {
|
||||
if (UNIV_LIKELY(!has_search_latch)
|
||||
&& buf_block_peek_if_too_old(block)) {
|
||||
|
||||
buf_page_make_young(page);
|
||||
}
|
||||
|
|
@ -889,6 +864,10 @@ btr_search_guess_on_hash(
|
|||
return(TRUE);
|
||||
|
||||
/*-------------------------------------------*/
|
||||
failure_unlock:
|
||||
if (UNIV_LIKELY(!has_search_latch)) {
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
}
|
||||
failure:
|
||||
info->n_hash_fail++;
|
||||
|
||||
|
|
@ -917,7 +896,6 @@ btr_search_drop_page_hash_index(
|
|||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
rec_t* rec;
|
||||
rec_t* sup;
|
||||
ulint fold;
|
||||
ulint prev_fold;
|
||||
dulint tree_id;
|
||||
|
|
@ -968,12 +946,10 @@ btr_search_drop_page_hash_index(
|
|||
|
||||
n_cached = 0;
|
||||
|
||||
sup = page_get_supremum_rec(page);
|
||||
|
||||
rec = page_get_infimum_rec(page);
|
||||
rec = page_rec_get_next(rec);
|
||||
|
||||
if (rec != sup) {
|
||||
if (!page_rec_is_supremum(rec)) {
|
||||
ut_a(n_fields <= rec_get_n_fields(rec, block->index));
|
||||
|
||||
if (n_bytes > 0) {
|
||||
|
|
@ -988,7 +964,7 @@ btr_search_drop_page_hash_index(
|
|||
heap = NULL;
|
||||
offsets = NULL;
|
||||
|
||||
while (rec != sup) {
|
||||
while (!page_rec_is_supremum(rec)) {
|
||||
/* FIXME: in a mixed tree, not all records may have enough
|
||||
ordering fields: */
|
||||
offsets = rec_get_offsets(rec, block->index,
|
||||
|
|
@ -1010,7 +986,7 @@ next_rec:
|
|||
prev_fold = fold;
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
|
|
@ -1090,7 +1066,6 @@ btr_search_build_page_hash_index(
|
|||
buf_block_t* block;
|
||||
rec_t* rec;
|
||||
rec_t* next_rec;
|
||||
rec_t* sup;
|
||||
ulint fold;
|
||||
ulint next_fold;
|
||||
dulint tree_id;
|
||||
|
|
@ -1158,15 +1133,13 @@ btr_search_build_page_hash_index(
|
|||
|
||||
tree_id = btr_page_get_index_id(page);
|
||||
|
||||
sup = page_get_supremum_rec(page);
|
||||
|
||||
rec = page_get_infimum_rec(page);
|
||||
rec = page_rec_get_next(rec);
|
||||
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
n_fields + (n_bytes > 0), &heap);
|
||||
|
||||
if (rec != sup) {
|
||||
if (!page_rec_is_supremum(rec)) {
|
||||
ut_a(n_fields <= rec_offs_n_fields(offsets));
|
||||
|
||||
if (n_bytes > 0) {
|
||||
|
|
@ -1188,7 +1161,7 @@ btr_search_build_page_hash_index(
|
|||
for (;;) {
|
||||
next_rec = page_rec_get_next(rec);
|
||||
|
||||
if (next_rec == sup) {
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
|
||||
if (side == BTR_SEARCH_RIGHT_SIDE) {
|
||||
|
||||
|
|
@ -1252,7 +1225,7 @@ exit_func:
|
|||
|
||||
mem_free(folds);
|
||||
mem_free(recs);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
}
|
||||
|
|
@ -1370,7 +1343,7 @@ btr_search_update_hash_on_delete(
|
|||
fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
|
||||
ULINT_UNDEFINED, &heap), block->curr_n_fields,
|
||||
block->curr_n_bytes, tree_id);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
rw_lock_x_lock(&btr_search_latch);
|
||||
|
|
@ -1443,7 +1416,6 @@ btr_search_update_hash_on_insert(
|
|||
{
|
||||
hash_table_t* table;
|
||||
buf_block_t* block;
|
||||
page_t* page;
|
||||
rec_t* rec;
|
||||
rec_t* ins_rec;
|
||||
rec_t* next_rec;
|
||||
|
|
@ -1488,19 +1460,18 @@ btr_search_update_hash_on_insert(
|
|||
ins_rec = page_rec_get_next(rec);
|
||||
next_rec = page_rec_get_next(ins_rec);
|
||||
|
||||
page = buf_frame_align(rec);
|
||||
offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, tree_id);
|
||||
|
||||
if (next_rec != page_get_supremum_rec(page)) {
|
||||
if (!page_rec_is_supremum(next_rec)) {
|
||||
offsets = rec_get_offsets(next_rec, cursor->index, offsets,
|
||||
n_fields + (n_bytes > 0), &heap);
|
||||
next_fold = rec_fold(next_rec, offsets, n_fields,
|
||||
n_bytes, tree_id);
|
||||
}
|
||||
|
||||
if (rec != page_get_infimum_rec(page)) {
|
||||
if (!page_rec_is_infimum(rec)) {
|
||||
offsets = rec_get_offsets(rec, cursor->index, offsets,
|
||||
n_fields + (n_bytes > 0), &heap);
|
||||
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
|
||||
|
|
@ -1534,7 +1505,7 @@ btr_search_update_hash_on_insert(
|
|||
}
|
||||
|
||||
check_next_rec:
|
||||
if (next_rec == page_get_supremum_rec(page)) {
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
|
||||
if (side == BTR_SEARCH_RIGHT_SIDE) {
|
||||
|
||||
|
|
@ -1573,7 +1544,7 @@ check_next_rec:
|
|||
}
|
||||
|
||||
function_exit:
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
if (locked) {
|
||||
|
|
@ -1662,7 +1633,7 @@ btr_search_validate(void)
|
|||
}
|
||||
|
||||
rw_lock_x_unlock(&btr_search_latch);
|
||||
if (heap) {
|
||||
if (UNIV_LIKELY_NULL(heap)) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue