Merge mskold@bk-internal.mysql.com:/home/bk/mysql-5.0

into mysql.com:/usr/local/home/marty/MySQL/mysql-5.0
This commit is contained in:
mskold@mysql.com 2005-06-21 08:59:37 +02:00
commit 981e845d8f
94 changed files with 2091 additions and 1894 deletions

View file

@ -303,6 +303,10 @@ SOURCE=..\mysys\mulalloc.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_access.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_alloc.c
# End Source File
# Begin Source File

View file

@ -1011,7 +1011,8 @@ static int read_lines(bool execute_commands)
a nil, it still needs the space in the linebuffer for it. This is,
naturally, undocumented.
*/
} while (linebuffer[0] <= linebuffer[1] + 1);
} while ((unsigned char)linebuffer[0] <=
(unsigned char)linebuffer[1] + 1);
line= buffer.c_ptr();
#endif /* __NETWARE__ */
#else

View file

@ -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);

View file

@ -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++) {

View file

@ -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);

View file

@ -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);
}

View file

@ -223,13 +223,14 @@ in the free list to the frames.
buf_pool_t* buf_pool = NULL; /* The buffer buf_pool of the database */
#ifdef UNIV_DEBUG
ulint buf_dbg_counter = 0; /* This is used to insert validation
operations in excution in the
debug version */
ibool buf_debug_prints = FALSE; /* If this is set TRUE,
the program prints info whenever
read-ahead or flush occurs */
#endif /* UNIV_DEBUG */
/************************************************************************
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value on
@ -1286,8 +1287,9 @@ buf_page_optimistic_get_func(
/* If AWE is used, block may have a different frame now, e.g., NULL */
if (block->state != BUF_BLOCK_FILE_PAGE || block->frame != guess) {
if (UNIV_UNLIKELY(block->state != BUF_BLOCK_FILE_PAGE)
|| UNIV_UNLIKELY(block->frame != guess)) {
exit_func:
mutex_exit(&(buf_pool->mutex));
return(FALSE);
@ -1320,19 +1322,17 @@ buf_page_optimistic_get_func(
fix_type = MTR_MEMO_PAGE_X_FIX;
}
if (!success) {
if (UNIV_UNLIKELY(!success)) {
mutex_enter(&(buf_pool->mutex));
block->buf_fix_count--;
#ifdef UNIV_SYNC_DEBUG
rw_lock_s_unlock(&(block->debug_latch));
#endif
mutex_exit(&(buf_pool->mutex));
return(FALSE);
#endif
goto exit_func;
}
if (!UT_DULINT_EQ(modify_clock, block->modify_clock)) {
if (UNIV_UNLIKELY(!UT_DULINT_EQ(modify_clock, block->modify_clock))) {
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(block->frame, SYNC_NO_ORDER_CHECK);
#endif /* UNIV_SYNC_DEBUG */
@ -1347,10 +1347,8 @@ buf_page_optimistic_get_func(
block->buf_fix_count--;
#ifdef UNIV_SYNC_DEBUG
rw_lock_s_unlock(&(block->debug_latch));
#endif
mutex_exit(&(buf_pool->mutex));
return(FALSE);
#endif
goto exit_func;
}
mtr_memo_push(mtr, block, fix_type);
@ -1368,7 +1366,7 @@ buf_page_optimistic_get_func(
#ifdef UNIV_DEBUG_FILE_ACCESSES
ut_a(block->file_page_was_freed == FALSE);
#endif
if (!accessed) {
if (UNIV_UNLIKELY(!accessed)) {
/* In the case of a first access, try to apply linear
read-ahead */
@ -1742,10 +1740,12 @@ buf_page_create(
/* If we get here, the page was not in buf_pool: init it there */
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr, "Creating space %lu page %lu to buffer\n",
(ulong) space, (ulong) offset);
}
#endif /* UNIV_DEBUG */
block = free_block;
@ -1896,9 +1896,11 @@ buf_page_io_complete(
rw_lock_x_unlock_gen(&(block->lock), BUF_IO_READ);
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fputs("Has read ", stderr);
}
#endif /* UNIV_DEBUG */
} else {
ut_ad(io_type == BUF_IO_WRITE);
@ -1911,17 +1913,21 @@ buf_page_io_complete(
buf_pool->n_pages_written++;
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fputs("Has written ", stderr);
}
#endif /* UNIV_DEBUG */
}
mutex_exit(&(buf_pool->mutex));
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr, "page space %lu page no %lu\n",
(ulong) block->space, (ulong) block->offset);
}
#endif /* UNIV_DEBUG */
}
/*************************************************************************
@ -1950,6 +1956,7 @@ buf_pool_invalidate(void)
mutex_exit(&(buf_pool->mutex));
}
#ifdef UNIV_DEBUG
/*************************************************************************
Validates the buffer buf_pool data structure. */
@ -2149,6 +2156,7 @@ buf_print(void)
ut_a(buf_validate());
}
#endif /* UNIV_DEBUG */
/*************************************************************************
Returns the number of latched pages in the buffer pool. */

View file

@ -586,11 +586,13 @@ buf_flush_try_page(
rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE);
}
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Flushing page space %lu, page no %lu \n",
(ulong) block->space, (ulong) block->offset);
}
#endif /* UNIV_DEBUG */
buf_flush_write_block_low(block);
@ -674,12 +676,14 @@ buf_flush_try_page(
rw_lock_s_lock_gen(&(block->lock), BUF_IO_WRITE);
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Flushing single page space %lu, page no %lu \n",
(ulong) block->space,
(ulong) block->offset);
}
#endif /* UNIV_DEBUG */
buf_flush_write_block_low(block);
@ -906,6 +910,7 @@ buf_flush_batch(
buf_flush_buffered_writes();
#ifdef UNIV_DEBUG
if (buf_debug_prints && page_count > 0) {
ut_a(flush_type == BUF_FLUSH_LRU
|| flush_type == BUF_FLUSH_LIST);
@ -914,6 +919,7 @@ buf_flush_batch(
: "Flushed %lu pages in flush list flush\n",
(ulong) page_count);
}
#endif /* UNIV_DEBUG */
if (page_count != ULINT_UNDEFINED)
srv_buf_pool_flushed+= page_count;

View file

@ -213,12 +213,14 @@ buf_LRU_search_and_free_block(
ut_a(block->in_LRU_list);
if (buf_flush_ready_for_replace(block)) {
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Putting space %lu page %lu to free list\n",
(ulong) block->space,
(ulong) block->offset);
}
#endif /* UNIV_DEBUG */
buf_LRU_block_remove_hashed_page(block);
@ -919,7 +921,8 @@ buf_LRU_block_free_hashed_page(
buf_LRU_block_free_non_file_page(block);
}
#ifdef UNIV_DEBUG
/**************************************************************************
Validates the LRU list. */
@ -1050,3 +1053,4 @@ buf_LRU_print(void)
mutex_exit(&(buf_pool->mutex));
}
#endif /* UNIV_DEBUG */

View file

@ -288,12 +288,14 @@ buf_read_ahead_random(
os_aio_simulated_wake_handler_threads();
#ifdef UNIV_DEBUG
if (buf_debug_prints && (count > 0)) {
fprintf(stderr,
"Random read-ahead space %lu offset %lu pages %lu\n",
(ulong) space, (ulong) offset,
(ulong) count);
}
#endif /* UNIV_DEBUG */
++srv_read_ahead_rnd;
return(count);
@ -575,11 +577,13 @@ buf_read_ahead_linear(
/* Flush pages from the end of the LRU list if necessary */
buf_flush_free_margin();
#ifdef UNIV_DEBUG
if (buf_debug_prints && (count > 0)) {
fprintf(stderr,
"LINEAR read-ahead space %lu offset %lu pages %lu\n",
(ulong) space, (ulong) offset, (ulong) count);
}
#endif /* UNIV_DEBUG */
++srv_read_ahead_seq;
return(count);
@ -641,11 +645,13 @@ buf_read_ibuf_merge_pages(
/* Flush pages from the end of the LRU list if necessary */
buf_flush_free_margin();
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Ibuf merge read-ahead space %lu pages %lu\n",
(ulong) space_ids[0], (ulong) n_stored);
}
#endif /* UNIV_DEBUG */
}
/************************************************************************
@ -711,8 +717,10 @@ buf_read_recv_pages(
/* Flush pages from the end of the LRU list if necessary */
buf_flush_free_margin();
#ifdef UNIV_DEBUG
if (buf_debug_prints) {
fprintf(stderr,
"Recovery applies read-ahead pages %lu\n", (ulong) n_stored);
}
#endif /* UNIV_DEBUG */
}

View file

@ -502,7 +502,7 @@ dtuple_convert_big_rec(
size = rec_get_converted_size(index, entry);
if (size > 1000000000) {
if (UNIV_UNLIKELY(size > 1000000000)) {
fprintf(stderr,
"InnoDB: Warning: tuple size very big: %lu\n", (ulong) size);
fputs("InnoDB: Tuple contents: ", stderr);

View file

@ -39,7 +39,6 @@ column definitions, or records in the insert buffer, we use this
charset-collation code for them. */
ulint data_mysql_default_charset_coll = 99999999;
ulint data_mysql_latin1_swedish_charset_coll = 99999999;
dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0, 0};
dtype_t* dtype_binary = &dtype_binary_val;
@ -64,9 +63,10 @@ dtype_get_at_most_n_mbchars(
{
#ifndef UNIV_HOTBACKUP
ut_a(data_len != UNIV_SQL_NULL);
ut_a(!(prefix_len % dtype->mbmaxlen));
ut_ad(!dtype->mbmaxlen || !(prefix_len % dtype->mbmaxlen));
if (dtype->mbminlen != dtype->mbmaxlen) {
ut_a(!(prefix_len % dtype->mbmaxlen));
return(innobase_get_at_most_n_mbchars(
dtype_get_charset_coll(dtype->prtype),
prefix_len, data_len, str));

View file

@ -66,15 +66,6 @@ dict_hdr_get_new_id(
dict_hdr = dict_hdr_get(&mtr);
id = mtr_read_dulint(dict_hdr + type, &mtr);
/* Add some dummy code here because otherwise pgcc seems to
compile wrong */
if (0 == ut_dulint_cmp(id, ut_dulint_max)) {
/* TO DO: remove this code, or make it conditional */
ut_dbg_null_ptr = 0;
}
id = ut_dulint_add(id, 1);
mlog_write_dulint(dict_hdr + type, id, &mtr);

View file

@ -736,7 +736,7 @@ dict_truncate_index_tree(
dulint index_id;
byte* ptr;
ulint len;
ibool comp;
ulint comp;
dict_index_t* index;
#ifdef UNIV_SYNC_DEBUG

View file

@ -1453,7 +1453,7 @@ dict_index_add_to_cache(
/* Increment the ord_part counts in columns which are ordering */
if (index->type & DICT_UNIVERSAL) {
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
n_ord = new_index->n_fields;
} else {
n_ord = dict_index_get_n_unique(new_index);
@ -1482,7 +1482,7 @@ dict_index_add_to_cache(
new_index->tree = tree;
}
if (!(new_index->type & DICT_UNIVERSAL)) {
if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) {
new_index->stat_n_diff_key_vals =
mem_heap_alloc(new_index->heap,
@ -1683,7 +1683,7 @@ dict_index_copy_types(
dtype_t* type;
ulint i;
if (index->type & DICT_UNIVERSAL) {
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
dtuple_set_types_binary(tuple, n_fields);
return;
@ -1779,7 +1779,7 @@ dict_index_build_internal_clust(
dict_index_copy(new_index, index, 0, index->n_fields);
}
if (index->type & DICT_UNIVERSAL) {
if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
/* No fixed number of fields determines an entry uniquely */
new_index->n_uniq = ULINT_MAX;
@ -3682,7 +3682,7 @@ dict_tree_find_index_low(
table = index->table;
if ((index->type & DICT_CLUSTERED)
&& (table->type != DICT_TABLE_ORDINARY)) {
&& UNIV_UNLIKELY(table->type != DICT_TABLE_ORDINARY)) {
/* Get the mix id of the record */
ut_a(!table->comp);
@ -3838,7 +3838,7 @@ dict_tree_build_node_ptr(
ind = dict_tree_find_index_low(tree, rec);
if (tree->type & DICT_UNIVERSAL) {
if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
/* In a universal index tree, we take the whole record as
the node pointer if the reord is on the leaf level,
on non-leaf levels we remove the last field, which
@ -3903,9 +3903,10 @@ dict_tree_copy_rec_order_prefix(
dict_index_t* index;
ulint n;
UNIV_PREFETCH_R(rec);
index = dict_tree_find_index_low(tree, rec);
if (tree->type & DICT_UNIVERSAL) {
if (UNIV_UNLIKELY(tree->type & DICT_UNIVERSAL)) {
ut_a(!index->table->comp);
n = rec_get_n_fields_old(rec);
} else {
@ -3957,7 +3958,7 @@ dict_index_calc_min_rec_len(
ulint sum = 0;
ulint i;
if (index->table->comp) {
if (UNIV_LIKELY(index->table->comp)) {
ulint nullable = 0;
sum = REC_N_NEW_EXTRA_BYTES;
for (i = 0; i < dict_index_get_n_fields(index); i++) {
@ -4277,9 +4278,11 @@ dict_index_print_low(
putc('\n', stderr);
/* btr_print_size(tree); */
#ifdef UNIV_BTR_PRINT
btr_print_size(tree);
/* btr_print_tree(tree, 7); */
btr_print_tree(tree, 7);
#endif /* UNIV_BTR_PRINT */
}
/**************************************************************************

View file

@ -42,6 +42,7 @@ dict_mem_table_create(
mem_heap_t* heap;
ut_ad(name);
ut_ad(comp == FALSE || comp == TRUE);
heap = mem_heap_create(DICT_HEAP_SIZE);

View file

@ -99,7 +99,6 @@ ulint fil_n_pending_tablespace_flushes = 0;
fil_addr_t fil_addr_null = {FIL_NULL, 0};
/* File node of a tablespace or the log data space */
typedef struct fil_node_struct fil_node_t;
struct fil_node_struct {
fil_space_t* space; /* backpointer to the space where this node
belongs */
@ -4046,7 +4045,7 @@ fil_aio_wait(
} else {
srv_set_io_thread_op_info(segment, "simulated aio handle");
ret = os_aio_simulated_handle(segment, (void**) &fil_node,
ret = os_aio_simulated_handle(segment, &fil_node,
&message, &type);
}

View file

@ -2325,7 +2325,6 @@ fseg_alloc_free_page_low(
dulint seg_id;
ulint used;
ulint reserved;
fil_addr_t first;
xdes_t* descr; /* extent of the hinted page */
ulint ret_page; /* the allocated page offset, FIL_NULL
if could not be allocated */
@ -2428,6 +2427,8 @@ fseg_alloc_free_page_low(
} else if (reserved - used > 0) {
/* 5. We take any unused page from the segment
==============================================*/
fil_addr_t first;
if (flst_get_len(seg_inode + FSEG_NOT_FULL, mtr) > 0) {
first = flst_get_first(seg_inode + FSEG_NOT_FULL,
mtr);
@ -2435,6 +2436,7 @@ fseg_alloc_free_page_low(
first = flst_get_first(seg_inode + FSEG_FREE, mtr);
} else {
ut_error;
return(FIL_NULL);
}
ret_descr = xdes_lst_get_descriptor(space, first, mtr);

View file

@ -1889,7 +1889,7 @@ ibuf_get_merge_page_nos(
contract the tree, FALSE if this is called
when a single page becomes full and we look
if it pays to read also nearby pages */
rec_t* first_rec,/* in: record from which we read up and down
rec_t* rec, /* in: record from which we read up and down
in the chain of records */
ulint* space_ids,/* in/out: space id's of the pages */
ib_longlong* space_versions,/* in/out: tablespace version
@ -1907,47 +1907,42 @@ ibuf_get_merge_page_nos(
ulint first_space_id;
ulint rec_page_no;
ulint rec_space_id;
rec_t* rec;
ulint sum_volumes;
ulint volume_for_page;
ulint rec_volume;
ulint limit;
page_t* page;
ulint n_pages;
*n_stored = 0;
limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool->curr_size / 4);
page = buf_frame_align(first_rec);
if (first_rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
first_rec = page_rec_get_prev(first_rec);
rec = page_rec_get_prev(rec);
}
if (first_rec == page_get_infimum_rec(page)) {
if (page_rec_is_infimum(rec)) {
first_rec = page_rec_get_next(first_rec);
rec = page_rec_get_next(rec);
}
if (first_rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
return(0);
}
rec = first_rec;
first_page_no = ibuf_rec_get_page_no(first_rec);
first_space_id = ibuf_rec_get_space(first_rec);
first_page_no = ibuf_rec_get_page_no(rec);
first_space_id = ibuf_rec_get_space(rec);
n_pages = 0;
prev_page_no = 0;
prev_space_id = 0;
/* Go backwards from the first_rec until we reach the border of the
/* Go backwards from the first rec until we reach the border of the
'merge area', or the page start or the limit of storeable pages is
reached */
while ((rec != page_get_infimum_rec(page)) && (n_pages < limit)) {
while (!page_rec_is_infimum(rec) && UNIV_LIKELY(n_pages < limit)) {
rec_page_no = ibuf_rec_get_page_no(rec);
rec_space_id = ibuf_rec_get_space(rec);
@ -1982,7 +1977,7 @@ ibuf_get_merge_page_nos(
volume_for_page = 0;
while (*n_stored < limit) {
if (rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
/* When no more records available, mark this with
another 'impossible' pair of space id, page no */
rec_page_no = 1;
@ -2311,12 +2306,12 @@ ibuf_get_volume_buffered(
page = buf_frame_align(rec);
if (rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
rec = page_rec_get_prev(rec);
}
for (;;) {
if (rec == page_get_infimum_rec(page)) {
if (page_rec_is_infimum(rec)) {
break;
}
@ -2351,7 +2346,7 @@ ibuf_get_volume_buffered(
rec = page_rec_get_prev(rec);
for (;;) {
if (rec == page_get_infimum_rec(prev_page)) {
if (page_rec_is_infimum(rec)) {
/* We cannot go to yet a previous page, because we
do not have the x-latch on it, and cannot acquire one
@ -2374,12 +2369,12 @@ ibuf_get_volume_buffered(
count_later:
rec = btr_pcur_get_rec(pcur);
if (rec != page_get_supremum_rec(page)) {
if (!page_rec_is_supremum(rec)) {
rec = page_rec_get_next(rec);
}
for (;;) {
if (rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
break;
}
@ -2414,7 +2409,7 @@ count_later:
rec = page_rec_get_next(rec);
for (;;) {
if (rec == page_get_supremum_rec(next_page)) {
if (page_rec_is_supremum(rec)) {
/* We give up */
@ -2815,7 +2810,7 @@ ibuf_insert_to_index_page(
ut_ad(ibuf_inside());
ut_ad(dtuple_check_typed(entry));
if (index->table->comp != page_is_comp(page)) {
if (UNIV_UNLIKELY(index->table->comp != !!page_is_comp(page))) {
fputs(
"InnoDB: Trying to insert a record from the insert buffer to an index page\n"
"InnoDB: but the 'compact' flag does not match!\n", stderr);
@ -2824,7 +2819,8 @@ ibuf_insert_to_index_page(
rec = page_rec_get_next(page_get_infimum_rec(page));
if (rec_get_n_fields(rec, index) != dtuple_get_n_fields(entry)) {
if (UNIV_UNLIKELY(rec_get_n_fields(rec, index)
!= dtuple_get_n_fields(entry))) {
fputs(
"InnoDB: Trying to insert a record from the insert buffer to an index page\n"
"InnoDB: but the number of fields does not match!\n", stderr);
@ -2848,7 +2844,7 @@ ibuf_insert_to_index_page(
if (low_match == dtuple_get_n_fields(entry)) {
rec = page_cur_get_rec(&page_cur);
btr_cur_del_unmark_for_ibuf(rec, index, mtr);
btr_cur_del_unmark_for_ibuf(rec, mtr);
} else {
rec = page_cur_tuple_insert(&page_cur, entry, index, mtr);
@ -2861,8 +2857,8 @@ ibuf_insert_to_index_page(
PAGE_CUR_LE, &page_cur);
/* This time the record must fit */
if (!page_cur_tuple_insert(&page_cur, entry,
index, mtr)) {
if (UNIV_UNLIKELY(!page_cur_tuple_insert(
&page_cur, entry, index, mtr))) {
ut_print_timestamp(stderr);
@ -2969,7 +2965,9 @@ ibuf_delete_rec(
btr_pcur_commit_specify_mtr(pcur, mtr);
fputs("InnoDB: Validating insert buffer tree:\n", stderr);
ut_a(btr_validate_tree(ibuf_data->index->tree));
if (!btr_validate_tree(ibuf_data->index->tree, NULL)) {
ut_error;
}
fprintf(stderr, "InnoDB: ibuf tree ok\n");
fflush(stderr);

View file

@ -168,7 +168,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 */
/****************************************************************
Frees a B-tree except the root page, which MUST be freed after this
@ -276,7 +276,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 */
/*****************************************************************
Deletes on the upper level the node pointer to a page. */
@ -336,7 +336,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 */
/***************************************************************
@ -398,6 +398,7 @@ btr_page_free_low(
page_t* page, /* in: page to be freed, x-latched */
ulint level, /* in: page level */
mtr_t* mtr); /* in: mtr */
#ifdef UNIV_BTR_PRINT
/*****************************************************************
Prints size info of a B-tree. */
@ -414,6 +415,7 @@ btr_print_tree(
dict_tree_t* tree, /* in: tree */
ulint width); /* in: print this many entries from start
and end */
#endif /* UNIV_BTR_PRINT */
/****************************************************************
Checks the size and number of fields in a record based on the definition of
the index. */
@ -434,7 +436,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 */
#define BTR_N_LEAF_PAGES 1
#define BTR_TOTAL_SIZE 2

View file

@ -200,10 +200,10 @@ btr_node_ptr_get_child_page_no(
page_no = mach_read_from_4(field);
if (page_no == 0) {
if (UNIV_UNLIKELY(page_no == 0)) {
fprintf(stderr,
"InnoDB: a nonsensical page number 0 in a node ptr record at offset %lu\n",
(unsigned long)(rec - buf_frame_align(rec)));
(ulong) ut_align_offset(rec, UNIV_PAGE_SIZE));
buf_page_print(buf_frame_align(rec));
}

View file

@ -284,7 +284,6 @@ 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 */
/*****************************************************************
Tries to compress a page of the tree on the leaf level. It is assumed
@ -389,7 +388,6 @@ 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: index corresponding to page */
page_t* page); /* in: page or NULL */
/***********************************************************************
Estimates the number of rows in a given index range. */

View file

@ -52,7 +52,9 @@ btr_cur_get_page(
/* out: pointer to page */
btr_cur_t* cursor) /* in: tree cursor */
{
return(buf_frame_align(page_cur_get_rec(&(cursor->page_cur))));
page_t* page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur)));
ut_ad(!!page_is_comp(page) == cursor->index->table->comp);
return(page);
}
/*************************************************************

View file

@ -56,9 +56,11 @@ Created 11/5/1995 Heikki Tuuri
#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
extern buf_pool_t* buf_pool; /* The buffer pool of the database */
#ifdef UNIV_DEBUG
extern ibool buf_debug_prints;/* If this is set TRUE, the program
prints info whenever read or flush
occurs */
#endif /* UNIV_DEBUG */
extern ulint srv_buf_pool_write_requests; /* variable to count write request
issued */
@ -382,10 +384,10 @@ Returns the value of the modify clock. The caller must have an s-lock
or x-lock on the block. */
UNIV_INLINE
dulint
buf_frame_get_modify_clock(
buf_block_get_modify_clock(
/*=======================*/
/* out: value */
buf_frame_t* frame); /* in: pointer to a frame */
buf_block_t* block); /* in: block */
/************************************************************************
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value
@ -480,12 +482,20 @@ buf_pool_is_block(
/*==============*/
/* out: TRUE if pointer to block */
void* ptr); /* in: pointer to memory */
#ifdef UNIV_DEBUG
/*************************************************************************
Validates the buffer pool data structure. */
ibool
buf_validate(void);
/*==============*/
/*************************************************************************
Prints info of the buffer pool data structure. */
void
buf_print(void);
/*============*/
#endif /* UNIV_DEBUG */
/************************************************************************
Prints a page to stderr. */
@ -494,12 +504,6 @@ buf_page_print(
/*===========*/
byte* read_buf); /* in: a database page */
/*************************************************************************
Prints info of the buffer pool data structure. */
void
buf_print(void);
/*============*/
/*************************************************************************
Returns the number of latched pages in the buffer pool. */
ulint

View file

@ -11,10 +11,11 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0rea.h"
#include "mtr0mtr.h"
#ifdef UNIV_DEBUG
extern ulint buf_dbg_counter; /* This is used to insert validation
operations in execution in the
debug version */
#endif /* UNIV_DEBUG */
/************************************************************************
Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
@ -26,12 +27,8 @@ buf_block_peek_if_too_old(
/* out: TRUE if should be made younger */
buf_block_t* block) /* in: block to make younger */
{
if (buf_pool->freed_page_clock >= block->freed_page_clock
+ 1 + (buf_pool->curr_size / 1024)) {
return(TRUE);
}
return(FALSE);
return(buf_pool->freed_page_clock >= block->freed_page_clock
+ 1 + (buf_pool->curr_size / 1024));
}
/*************************************************************************
@ -210,8 +207,8 @@ buf_block_align(
frame_zero = buf_pool->frame_zero;
if ((ulint)ptr < (ulint)frame_zero
|| (ulint)ptr > (ulint)(buf_pool->high_end)) {
if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero)
|| UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) {
ut_print_timestamp(stderr);
fprintf(stderr,
@ -246,8 +243,8 @@ buf_frame_align(
frame = ut_align_down(ptr, UNIV_PAGE_SIZE);
if (((ulint)frame < (ulint)(buf_pool->frame_zero))
|| (ulint)frame >= (ulint)(buf_pool->high_end)) {
if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero))
|| UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) {
ut_print_timestamp(stderr);
fprintf(stderr,
@ -485,17 +482,11 @@ Returns the value of the modify clock. The caller must have an s-lock
or x-lock on the block. */
UNIV_INLINE
dulint
buf_frame_get_modify_clock(
buf_block_get_modify_clock(
/*=======================*/
/* out: value */
buf_frame_t* frame) /* in: pointer to a frame */
buf_block_t* block) /* in: block */
{
buf_block_t* block;
ut_ad(frame);
block = buf_block_align(frame);
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));

View file

@ -122,6 +122,7 @@ void
buf_LRU_make_block_old(
/*===================*/
buf_block_t* block); /* in: control block */
#ifdef UNIV_DEBUG
/**************************************************************************
Validates the LRU list. */
@ -134,6 +135,7 @@ Prints the LRU list. */
void
buf_LRU_print(void);
/*===============*/
#endif /* UNIV_DEBUG */
#ifndef UNIV_NONINL
#include "buf0lru.ic"

View file

@ -12,7 +12,7 @@ Created 1/16/1996 Heikki Tuuri
#include "univ.i"
extern ulint data_mysql_default_charset_coll;
extern ulint data_mysql_latin1_swedish_charset_coll;
#define DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL 8
/* SQL data type struct */
typedef struct dtype_struct dtype_t;

View file

@ -388,8 +388,8 @@ dtype_get_fixed_size(
dtype_get_charset_coll(type->prtype),
&mbminlen, &mbmaxlen);
if (type->mbminlen != mbminlen
|| type->mbmaxlen != mbmaxlen) {
if (UNIV_UNLIKELY(type->mbminlen != mbminlen)
|| UNIV_UNLIKELY(type->mbmaxlen != mbmaxlen)) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: "

View file

@ -132,7 +132,7 @@ void
dyn_push_string(
/*============*/
dyn_array_t* arr, /* in: dyn array */
byte* str, /* in: string to write */
const byte* str, /* in: string to write */
ulint len); /* in: string length */
/*#################################################################*/

View file

@ -324,10 +324,9 @@ void
dyn_push_string(
/*============*/
dyn_array_t* arr, /* in: dyn array */
byte* str, /* in: string to write */
const byte* str, /* in: string to write */
ulint len) /* in: string length */
{
byte* ptr;
ulint n_copied;
while (len > 0) {
@ -337,9 +336,7 @@ dyn_push_string(
n_copied = len;
}
ptr = (byte*) dyn_array_push(arr, n_copied);
ut_memcpy(ptr, str, n_copied);
memcpy(dyn_array_push(arr, n_copied), str, n_copied);
str += n_copied;
len -= n_copied;

View file

@ -19,7 +19,9 @@ Created 5/7/1996 Heikki Tuuri
#include "read0types.h"
#include "hash0hash.h"
#ifdef UNIV_DEBUG
extern ibool lock_print_waits;
#endif /* UNIV_DEBUG */
/* Buffer for storing information about the most recent deadlock error */
extern FILE* lock_latest_err_file;
@ -216,6 +218,7 @@ actual record is being moved. */
void
lock_rec_store_on_page_infimum(
/*===========================*/
page_t* page, /* in: page containing the record */
rec_t* rec); /* in: record whose lock state is stored
on the infimum record of the same page; lock
bits are reset on the record */
@ -412,9 +415,7 @@ lock_table(
/* out: DB_SUCCESS, DB_LOCK_WAIT,
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing;
if LOCK_TABLE_EXP bits are set,
creates an explicit table lock */
does nothing */
dict_table_t* table, /* in: database table in dictionary cache */
ulint mode, /* in: lock mode */
que_thr_t* thr); /* in: query thread */
@ -451,15 +452,6 @@ lock_release_off_kernel(
/*====================*/
trx_t* trx); /* in: transaction */
/*************************************************************************
Releases table locks explicitly requested with LOCK TABLES (indicated by
lock type LOCK_TABLE_EXP), and releases possible other transactions waiting
because of these locks. */
void
lock_release_tables_off_kernel(
/*===========================*/
trx_t* trx); /* in: transaction */
/*************************************************************************
Cancels a waiting lock request and releases possible other transactions
waiting behind it. */
@ -618,9 +610,6 @@ extern lock_sys_t* lock_sys;
/* Lock types */
#define LOCK_TABLE 16 /* these type values should be so high that */
#define LOCK_REC 32 /* they can be ORed to the lock mode */
#define LOCK_TABLE_EXP 80 /* explicit table lock (80 = 16 + 64) */
#define LOCK_TABLE_TRANSACTIONAL 144
/* transactional table lock (144 = 16 + 128)*/
#define LOCK_TYPE_MASK 0xF0UL /* mask used to extract lock type from the
type_mode field in a lock */
/* Waiting lock flag */

View file

@ -17,8 +17,12 @@ Created 12/9/1995 Heikki Tuuri
typedef struct log_struct log_t;
typedef struct log_group_struct log_group_t;
#ifdef UNIV_DEBUG
extern ibool log_do_write;
extern ibool log_debug_writes;
#else /* UNIV_DEBUG */
# define log_do_write TRUE
#endif /* UNIV_DEBUG */
/* Wait modes for log_write_up_to */
#define LOG_NO_WAIT 91

View file

@ -52,6 +52,27 @@ mach_read_from_2(
/*=============*/
/* out: ulint integer, >= 0, < 64k */
byte* b); /* in: pointer to two bytes */
/************************************************************
The following function is used to convert a 16-bit data item
to the canonical format, for fast bytewise equality test
against memory. */
UNIV_INLINE
uint16
mach_encode_2(
/*==========*/
/* out: 16-bit integer in canonical format */
ulint n); /* in: integer in machine-dependent format */
/************************************************************
The following function is used to convert a 16-bit data item
from the canonical format, for fast bytewise equality test
against memory. */
UNIV_INLINE
ulint
mach_decode_2(
/*==========*/
/* out: integer in machine-dependent format */
uint16 n); /* in: 16-bit integer in canonical format */
/***********************************************************
The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */

View file

@ -68,6 +68,37 @@ mach_read_from_2(
);
}
/************************************************************
The following function is used to convert a 16-bit data item
to the canonical format, for fast bytewise equality test
against memory. */
UNIV_INLINE
uint16
mach_encode_2(
/*==========*/
/* out: 16-bit integer in canonical format */
ulint n) /* in: integer in machine-dependent format */
{
uint16 ret;
ut_ad(2 == sizeof ret);
mach_write_to_2((byte*) &ret, n);
return(ret);
}
/************************************************************
The following function is used to convert a 16-bit data item
from the canonical format, for fast bytewise equality test
against memory. */
UNIV_INLINE
ulint
mach_decode_2(
/*==========*/
/* out: integer in machine-dependent format */
uint16 n) /* in: 16-bit integer in canonical format */
{
ut_ad(2 == sizeof n);
return(mach_read_from_2((byte*) &n));
}
/***********************************************************
The following function is used to store data in 3 consecutive
bytes. We store the most significant byte to the lowest address. */

View file

@ -623,7 +623,7 @@ mem_strdupq(
}
*d++ = q;
*d++ = '\0';
ut_ad(len == d - dst);
ut_ad((ssize_t) len == d - dst);
return(dst);
}

View file

@ -41,10 +41,10 @@ corresponding log record to the mini-transaction log. */
void
mlog_write_string(
/*==============*/
byte* ptr, /* in: pointer where to write */
byte* str, /* in: string to write */
ulint len, /* in: string length */
mtr_t* mtr); /* in: mini-transaction handle */
byte* ptr, /* in: pointer where to write */
const byte* str, /* in: string to write */
ulint len, /* in: string length */
mtr_t* mtr); /* in: mini-transaction handle */
/************************************************************
Writes initial part of a log record consisting of one-byte item
type and four-byte space and page numbers. */
@ -85,9 +85,9 @@ Catenates n bytes to the mtr log. */
void
mlog_catenate_string(
/*=================*/
mtr_t* mtr, /* in: mtr */
byte* str, /* in: string to write */
ulint len); /* in: string length */
mtr_t* mtr, /* in: mtr */
const byte* str, /* in: string to write */
ulint len); /* in: string length */
/************************************************************
Catenates a compressed ulint to mlog. */
UNIV_INLINE

View file

@ -112,7 +112,11 @@ flag value must give the length also! */
/* mark compact clustered index
record deleted */
#define MLOG_COMP_REC_SEC_DELETE_MARK ((byte)40)/* mark compact secondary index
record deleted */
record deleted; this log
record type is redundant, as
MLOG_REC_SEC_DELETE_MARK is
independent of the record
format. */
#define MLOG_COMP_REC_UPDATE_IN_PLACE ((byte)41)/* update of a compact record,
preserves record field sizes */
#define MLOG_COMP_REC_DELETE ((byte)42) /* delete a compact record

View file

@ -17,6 +17,8 @@ Created 10/21/1995 Heikki Tuuri
#include <time.h>
#endif
typedef struct fil_node_struct fil_node_t;
extern ibool os_do_not_call_flush_at_each_write;
extern ibool os_has_said_disk_full;
extern ibool os_aio_print_debug;
@ -563,7 +565,7 @@ os_aio(
ulint offset_high, /* in: most significant 32 bits of
offset */
ulint n, /* in: number of bytes to read or write */
void* message1,/* in: messages for the aio handler (these
fil_node_t* message1,/* in: messages for the aio handler (these
can be used to identify a completed aio
operation); if mode is OS_AIO_SYNC, these
are ignored */
@ -621,7 +623,7 @@ os_aio_windows_handle(
ignored */
ulint pos, /* this parameter is used only in sync aio:
wait for the aio slot at this position */
void** message1, /* out: the messages passed with the aio
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
@ -641,7 +643,7 @@ os_aio_posix_handle(
/*================*/
/* out: TRUE if the aio operation succeeded */
ulint array_no, /* in: array number 0 - 3 */
void** message1, /* out: the messages passed with the aio
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
@ -661,7 +663,7 @@ os_aio_simulated_handle(
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
the last are the non-ibuf write threads */
void** message1, /* out: the messages passed with the aio
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
@ -688,6 +690,8 @@ Refreshes the statistics used to print per-second averages. */
void
os_aio_refresh_stats(void);
/*======================*/
#ifdef UNIV_DEBUG
/**************************************************************************
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
@ -695,6 +699,7 @@ no pending io operations. */
ibool
os_aio_all_slots_free(void);
/*=======================*/
#endif /* UNIV_DEBUG */
/***********************************************************************
This function returns information about the specified file */

View file

@ -78,16 +78,16 @@ UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
/* out: TRUE if at start */
page_cur_t* cur); /* in: cursor */
/* out: TRUE if at start */
const page_cur_t* cur); /* in: cursor */
/*************************************************************
Returns TRUE if the cursor is after last user record. */
UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
/* out: TRUE if at end */
page_cur_t* cur); /* in: cursor */
/* out: TRUE if at end */
const page_cur_t* cur); /* in: cursor */
/**************************************************************
Positions the cursor on the given record. */
UNIV_INLINE

View file

@ -69,15 +69,10 @@ UNIV_INLINE
ibool
page_cur_is_before_first(
/*=====================*/
/* out: TRUE if at start */
page_cur_t* cur) /* in: cursor */
/* out: TRUE if at start */
const page_cur_t* cur) /* in: cursor */
{
if (page_get_infimum_rec(page_cur_get_page(cur)) == cur->rec) {
return(TRUE);
}
return(FALSE);
return(page_rec_is_infimum(cur->rec));
}
/*************************************************************
@ -86,15 +81,10 @@ UNIV_INLINE
ibool
page_cur_is_after_last(
/*===================*/
/* out: TRUE if at end */
page_cur_t* cur) /* in: cursor */
/* out: TRUE if at end */
const page_cur_t* cur) /* in: cursor */
{
if (page_get_supremum_rec(page_cur_get_page(cur)) == cur->rec) {
return(TRUE);
}
return(FALSE);
return(page_rec_is_supremum(cur->rec));
}
/**************************************************************

View file

@ -373,13 +373,21 @@ page_dir_find_owner_slot(
/****************************************************************
Determine whether the page is in new-style compact format. */
UNIV_INLINE
ibool
ulint
page_is_comp(
/*=========*/
/* out: TRUE if the page is in compact format
FALSE if it is in old-style format */
/* out: nonzero if the page is in compact
format, zero if it is in old-style format */
page_t* page); /* in: index page */
/****************************************************************
TRUE if the record is on a page in compact format. */
UNIV_INLINE
ulint
page_rec_is_comp(
/*=============*/
/* out: nonzero if in compact format */
const rec_t* rec); /* in: record */
/****************************************************************
Gets the pointer to the next record on the page. */
UNIV_INLINE
rec_t*
@ -407,6 +415,30 @@ page_rec_get_prev(
/* out: pointer to previous record */
rec_t* rec); /* in: pointer to record,
must not be page infimum */
/****************************************************************
TRUE if the record is a user record on the page. */
UNIV_INLINE
ibool
page_rec_is_user_rec_low(
/*=====================*/
/* out: TRUE if a user record */
ulint offset);/* in: record offset on page */
/****************************************************************
TRUE if the record is the supremum record on a page. */
UNIV_INLINE
ibool
page_rec_is_supremum_low(
/*=====================*/
/* out: TRUE if the supremum record */
ulint offset);/* in: record offset on page */
/****************************************************************
TRUE if the record is the infimum record on a page. */
UNIV_INLINE
ibool
page_rec_is_infimum_low(
/*=====================*/
/* out: TRUE if the infimum record */
ulint offset);/* in: record offset on page */
/****************************************************************
TRUE if the record is a user record on the page. */
@ -414,40 +446,24 @@ UNIV_INLINE
ibool
page_rec_is_user_rec(
/*=================*/
/* out: TRUE if a user record */
rec_t* rec); /* in: record */
/* out: TRUE if a user record */
const rec_t* rec); /* in: record */
/****************************************************************
TRUE if the record is the supremum record on a page. */
UNIV_INLINE
ibool
page_rec_is_supremum(
/*=================*/
/* out: TRUE if the supremum record */
rec_t* rec); /* in: record */
/* out: TRUE if the supremum record */
const rec_t* rec); /* in: record */
/****************************************************************
TRUE if the record is the infimum record on a page. */
UNIV_INLINE
ibool
page_rec_is_infimum(
/*================*/
/* out: TRUE if the infimum record */
rec_t* rec); /* in: record */
/****************************************************************
TRUE if the record is the first user record on the page. */
UNIV_INLINE
ibool
page_rec_is_first_user_rec(
/*=======================*/
/* out: TRUE if first user record */
rec_t* rec); /* in: record */
/****************************************************************
TRUE if the record is the last user record on the page. */
UNIV_INLINE
ibool
page_rec_is_last_user_rec(
/*======================*/
/* out: TRUE if last user record */
rec_t* rec); /* in: record */
/* out: TRUE if the infimum record */
const rec_t* rec); /* in: record */
/*******************************************************************
Looks for the record which owns the given record. */
UNIV_INLINE
@ -495,7 +511,7 @@ ulint
page_get_free_space_of_empty(
/*=========================*/
/* out: free space */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
__attribute__((const));
/****************************************************************
Returns the sum of the sizes of the records in the record list
@ -539,7 +555,7 @@ page_create(
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
mtr_t* mtr, /* in: mini-transaction handle */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/*****************************************************************
Differs from page_copy_rec_list_end, because this function does not
touch the lock table and max trx id on page. */
@ -673,7 +689,7 @@ page_parse_create(
/* 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 */
/****************************************************************

View file

@ -155,14 +155,27 @@ page_header_reset_last_insert(
/****************************************************************
Determine whether the page is in new-style compact format. */
UNIV_INLINE
ibool
ulint
page_is_comp(
/*=========*/
/* out: TRUE if the page is in compact format
FALSE if it is in old-style format */
page_t* page) /* in: index page */
/* out: nonzero if the page is in compact
format, zero if it is in old-style format */
page_t* page) /* in: index page */
{
return(!!(page_header_get_field(page, PAGE_N_HEAP) & 0x8000));
return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000,
0x8000));
}
/****************************************************************
TRUE if the record is on a page in compact format. */
UNIV_INLINE
ulint
page_rec_is_comp(
/*=============*/
/* out: nonzero if in compact format */
const rec_t* rec) /* in: record */
{
return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE)));
}
/****************************************************************
@ -201,28 +214,85 @@ page_get_supremum_rec(
}
}
/****************************************************************
TRUE if the record is a user record on the page. */
UNIV_INLINE
ibool
page_rec_is_user_rec_low(
/*=====================*/
/* out: TRUE if a user record */
ulint offset) /* in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
#if PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM
# error "PAGE_OLD_INFIMUM < PAGE_NEW_INFIMUM"
#endif
#if PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM
# error "PAGE_OLD_SUPREMUM < PAGE_NEW_SUPREMUM"
#endif
#if PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM
# error "PAGE_NEW_INFIMUM > PAGE_OLD_SUPREMUM"
#endif
#if PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM
# error "PAGE_OLD_INFIMUM > PAGE_NEW_SUPREMUM"
#endif
#if PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END
# error "PAGE_NEW_SUPREMUM > PAGE_OLD_SUPREMUM_END"
#endif
#if PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END
# error "PAGE_OLD_SUPREMUM > PAGE_NEW_SUPREMUM_END"
#endif
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
return(UNIV_LIKELY(offset != PAGE_NEW_SUPREMUM)
&& UNIV_LIKELY(offset != PAGE_NEW_INFIMUM)
&& UNIV_LIKELY(offset != PAGE_OLD_INFIMUM)
&& UNIV_LIKELY(offset != PAGE_OLD_SUPREMUM));
}
/****************************************************************
TRUE if the record is the supremum record on a page. */
UNIV_INLINE
ibool
page_rec_is_supremum_low(
/*=====================*/
/* out: TRUE if the supremum record */
ulint offset) /* in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
return(UNIV_UNLIKELY(offset == PAGE_NEW_SUPREMUM)
|| UNIV_UNLIKELY(offset == PAGE_OLD_SUPREMUM));
}
/****************************************************************
TRUE if the record is the infimum record on a page. */
UNIV_INLINE
ibool
page_rec_is_infimum_low(
/*=====================*/
/* out: TRUE if the infimum record */
ulint offset) /* in: record offset on page */
{
ut_ad(offset >= PAGE_NEW_INFIMUM);
ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
return(UNIV_UNLIKELY(offset == PAGE_NEW_INFIMUM)
|| UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM));
}
/****************************************************************
TRUE if the record is a user record on the page. */
UNIV_INLINE
ibool
page_rec_is_user_rec(
/*=================*/
/* out: TRUE if a user record */
rec_t* rec) /* in: record */
/* out: TRUE if a user record */
const rec_t* rec) /* in: record */
{
ut_ad(rec);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
return(FALSE);
}
if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
return(FALSE);
}
return(TRUE);
return(page_rec_is_user_rec_low(
ut_align_offset(rec, UNIV_PAGE_SIZE)));
}
/****************************************************************
@ -231,17 +301,11 @@ UNIV_INLINE
ibool
page_rec_is_supremum(
/*=================*/
/* out: TRUE if the supremum record */
rec_t* rec) /* in: record */
/* out: TRUE if the supremum record */
const rec_t* rec) /* in: record */
{
ut_ad(rec);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
return(TRUE);
}
return(FALSE);
return(page_rec_is_supremum_low(
ut_align_offset(rec, UNIV_PAGE_SIZE)));
}
/****************************************************************
@ -250,67 +314,11 @@ UNIV_INLINE
ibool
page_rec_is_infimum(
/*================*/
/* out: TRUE if the infimum record */
rec_t* rec) /* in: record */
/* out: TRUE if the infimum record */
const rec_t* rec) /* in: record */
{
ut_ad(rec);
if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
return(TRUE);
}
return(FALSE);
}
/****************************************************************
TRUE if the record is the first user record on the page. */
UNIV_INLINE
ibool
page_rec_is_first_user_rec(
/*=======================*/
/* out: TRUE if first user record */
rec_t* rec) /* in: record */
{
ut_ad(rec);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
return(FALSE);
}
if (rec == page_rec_get_next(
page_get_infimum_rec(buf_frame_align(rec)))) {
return(TRUE);
}
return(FALSE);
}
/****************************************************************
TRUE if the record is the last user record on the page. */
UNIV_INLINE
ibool
page_rec_is_last_user_rec(
/*======================*/
/* out: TRUE if last user record */
rec_t* rec) /* in: record */
{
ut_ad(rec);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
return(FALSE);
}
if (page_rec_get_next(rec)
== page_get_supremum_rec(buf_frame_align(rec))) {
return(TRUE);
}
return(FALSE);
return(page_rec_is_infimum_low(
ut_align_offset(rec, UNIV_PAGE_SIZE)));
}
/*****************************************************************
@ -340,22 +348,26 @@ page_cmp_dtuple_rec_with_match(
matched; when function returns contains the
value for current comparison */
{
page_t* page;
ulint rec_offset;
ut_ad(dtuple_check_typed(dtuple));
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
page = buf_frame_align(rec);
rec_offset = ut_align_offset(rec, UNIV_PAGE_SIZE);
if (rec == page_get_infimum_rec(page)) {
if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_INFIMUM)
|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_INFIMUM)) {
return(1);
} else if (rec == page_get_supremum_rec(page)) {
}
if (UNIV_UNLIKELY(rec_offset == PAGE_NEW_SUPREMUM)
|| UNIV_UNLIKELY(rec_offset == PAGE_OLD_SUPREMUM)) {
return(-1);
} else {
return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
}
return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
matched_fields,
matched_bytes));
}
}
/*****************************************************************
@ -482,7 +494,7 @@ page_dir_slot_set_rec(
{
ut_ad(page_rec_check(rec));
mach_write_to_2(slot, rec - buf_frame_align(rec));
mach_write_to_2(slot, ut_align_offset(rec, UNIV_PAGE_SIZE));
}
/*******************************************************************
@ -494,8 +506,8 @@ page_dir_slot_get_n_owned(
/* out: number of records */
page_dir_slot_t* slot) /* in: page directory slot */
{
return(rec_get_n_owned(page_dir_slot_get_rec(slot),
page_is_comp(buf_frame_align(slot))));
rec_t* rec = page_dir_slot_get_rec(slot);
return(rec_get_n_owned(rec, page_rec_is_comp(rec)));
}
/*******************************************************************
@ -508,8 +520,8 @@ page_dir_slot_set_n_owned(
ulint n) /* in: number of records owned
by the slot */
{
rec_set_n_owned(page_dir_slot_get_rec(slot),
page_is_comp(buf_frame_align(slot)), n);
rec_t* rec = page_dir_slot_get_rec(slot);
rec_set_n_owned(rec, page_rec_is_comp(rec), n);
}
/****************************************************************
@ -540,26 +552,25 @@ page_rec_get_next(
ut_ad(page_rec_check(rec));
page = buf_frame_align(rec);
page = ut_align_down(rec, UNIV_PAGE_SIZE);
offs = rec_get_next_offs(rec, page_is_comp(page));
if (offs >= UNIV_PAGE_SIZE) {
if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) {
fprintf(stderr,
"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n",
(ulong)offs, (ulong)(rec - page));
fprintf(stderr,
"\nInnoDB: rec address %p, first buffer frame %p\n"
"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n"
"InnoDB: rec address %p, first buffer frame %p\n"
"InnoDB: buffer pool high end %p, buf fix count %lu\n",
(ulong)offs, (ulong)(rec - page),
rec, buf_pool->frame_zero,
buf_pool->high_end,
(ulong)buf_block_align(rec)->buf_fix_count);
buf_page_print(page);
ut_a(0);
ut_error;
}
if (offs == 0) {
if (UNIV_UNLIKELY(offs == 0)) {
return(NULL);
}
@ -581,15 +592,12 @@ page_rec_set_next(
ulint offs;
ut_ad(page_rec_check(rec));
ut_a((next == NULL)
|| (buf_frame_align(rec) == buf_frame_align(next)));
page = buf_frame_align(rec);
ut_ad(rec != page_get_supremum_rec(page));
ut_ad(next != page_get_infimum_rec(page));
ut_ad(!page_rec_is_supremum(rec));
page = ut_align_down(rec, UNIV_PAGE_SIZE);
if (next) {
ut_ad(!page_rec_is_infimum(next));
ut_ad(page == ut_align_down(next, UNIV_PAGE_SIZE));
offs = (ulint) (next - page);
} else {
offs = 0;
@ -613,13 +621,12 @@ page_rec_get_prev(
rec_t* rec2;
rec_t* prev_rec = NULL;
page_t* page;
ibool comp;
ut_ad(page_rec_check(rec));
page = buf_frame_align(rec);
page = ut_align_down(rec, UNIV_PAGE_SIZE);
ut_ad(rec != page_get_infimum_rec(page));
ut_ad(!page_rec_is_infimum(rec));
slot_no = page_dir_find_owner_slot(rec);
@ -628,7 +635,6 @@ page_rec_get_prev(
slot = page_dir_get_nth_slot(page, slot_no - 1);
rec2 = page_dir_slot_get_rec(slot);
comp = page_is_comp(page);
while (rec != rec2) {
prev_rec = rec2;
@ -649,13 +655,16 @@ page_rec_find_owner_rec(
/* out: the owner record */
rec_t* rec) /* in: the physical record */
{
ibool comp;
ut_ad(page_rec_check(rec));
comp = page_is_comp(buf_frame_align(rec));
while (rec_get_n_owned(rec, comp) == 0) {
rec = page_rec_get_next(rec);
if (page_rec_is_comp(rec)) {
while (rec_get_n_owned(rec, TRUE) == 0) {
rec = page_rec_get_next(rec);
}
} else {
while (rec_get_n_owned(rec, FALSE) == 0) {
rec = page_rec_get_next(rec);
}
}
return(rec);
@ -691,10 +700,17 @@ ulint
page_get_free_space_of_empty(
/*=========================*/
/* out: free space */
ibool comp) /* in: TRUE=compact page layout */
ulint comp) /* in: nonzero=compact page layout */
{
if (UNIV_LIKELY(comp)) {
return((ulint)(UNIV_PAGE_SIZE
- PAGE_NEW_SUPREMUM_END
- PAGE_DIR
- 2 * PAGE_DIR_SLOT_SIZE));
}
return((ulint)(UNIV_PAGE_SIZE
- (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END)
- PAGE_OLD_SUPREMUM_END
- PAGE_DIR
- 2 * PAGE_DIR_SLOT_SIZE));
}
@ -716,17 +732,21 @@ page_get_max_insert_size(
{
ulint occupied;
ulint free_space;
ibool comp;
comp = page_is_comp(page);
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
- (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END)
+ page_dir_calc_reserved_space(
if (page_is_comp(page)) {
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
- PAGE_NEW_SUPREMUM_END + page_dir_calc_reserved_space(
n_recs + page_dir_get_n_heap(page) - 2);
free_space = page_get_free_space_of_empty(comp);
free_space = page_get_free_space_of_empty(TRUE);
} else {
occupied = page_header_get_field(page, PAGE_HEAP_TOP)
- PAGE_OLD_SUPREMUM_END + page_dir_calc_reserved_space(
n_recs + page_dir_get_n_heap(page) - 2);
free_space = page_get_free_space_of_empty(FALSE);
}
/* Above the 'n_recs +' part reserves directory space for the new
inserted records; the '- 2' excludes page infimum and supremum
records */
@ -752,14 +772,11 @@ page_get_max_insert_size_after_reorganize(
{
ulint occupied;
ulint free_space;
ibool comp;
comp = page_is_comp(page);
occupied = page_get_data_size(page)
+ page_dir_calc_reserved_space(n_recs + page_get_n_recs(page));
free_space = page_get_free_space_of_empty(comp);
free_space = page_get_free_space_of_empty(page_is_comp(page));
if (occupied > free_space) {
@ -783,6 +800,7 @@ page_mem_free(
ulint garbage;
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
free = page_header_get_ptr(page, PAGE_FREE);
page_rec_set_next(rec, free);

View file

@ -71,13 +71,8 @@ read_view_sees_trx_id(
cmp = ut_dulint_cmp(trx_id,
read_view_get_nth_trx_id(view, n_ids - i - 1));
if (0 == cmp) {
return(FALSE);
} else if (cmp < 0) {
return(TRUE);
if (cmp <= 0) {
return(cmp < 0);
}
}

View file

@ -51,7 +51,7 @@ rec_get_next_offs(
/* out: the page offset of the next
chained record */
rec_t* rec, /* in: physical record */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the next record offset field
of the record. */
@ -60,7 +60,7 @@ void
rec_set_next_offs(
/*==============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint next); /* in: offset of the next record */
/**********************************************************
The following function is used to get the number of fields
@ -90,7 +90,7 @@ rec_get_n_owned(
/*============*/
/* out: number of owned records */
rec_t* rec, /* in: physical record */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the number of owned
records. */
@ -99,7 +99,7 @@ void
rec_set_n_owned(
/*============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint n_owned); /* in: the number of owned */
/**********************************************************
The following function is used to retrieve the info bits of
@ -110,7 +110,7 @@ rec_get_info_bits(
/*==============*/
/* out: info bits */
rec_t* rec, /* in: physical record */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the info bits of a record. */
UNIV_INLINE
@ -118,7 +118,7 @@ void
rec_set_info_bits(
/*==============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint bits); /* in: info bits */
/**********************************************************
The following function retrieves the status bits of a new-style record. */
@ -147,7 +147,7 @@ rec_get_info_and_status_bits(
/*=========================*/
/* out: info bits */
rec_t* rec, /* in: physical record */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
@ -156,18 +156,18 @@ void
rec_set_info_and_status_bits(
/*=========================*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint bits); /* in: info bits */
/**********************************************************
The following function tells if record is delete marked. */
UNIV_INLINE
ibool
ulint
rec_get_deleted_flag(
/*=================*/
/* out: TRUE if delete marked */
/* out: nonzero if delete marked */
rec_t* rec, /* in: physical record */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the deleted bit. */
UNIV_INLINE
@ -175,8 +175,8 @@ void
rec_set_deleted_flag(
/*=================*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ibool flag); /* in: TRUE if delete marked */
ulint comp, /* in: nonzero=compact page format */
ulint flag); /* in: nonzero if delete marked */
/**********************************************************
The following function tells if a new-style record is a node pointer. */
UNIV_INLINE
@ -186,14 +186,6 @@ rec_get_node_ptr_flag(
/* out: TRUE if node pointer */
rec_t* rec); /* in: physical record */
/**********************************************************
The following function is used to flag a record as a node pointer. */
UNIV_INLINE
void
rec_set_node_ptr_flag(
/*=================*/
rec_t* rec, /* in: physical record */
ibool flag); /* in: TRUE if the record is a node pointer */
/**********************************************************
The following function is used to get the order number
of the record in the heap of the index page. */
UNIV_INLINE
@ -202,7 +194,7 @@ rec_get_heap_no(
/*=============*/
/* out: heap order number */
rec_t* rec, /* in: physical record */
ibool comp); /* in: TRUE=compact page format */
ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the heap number
field in the record. */
@ -211,7 +203,7 @@ void
rec_set_heap_no(
/*=============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint heap_no);/* in: the heap number */
/**********************************************************
The following function is used to test whether the data offsets
@ -305,27 +297,18 @@ rec_get_nth_field(
Determine if the offsets are for a record in the new
compact format. */
UNIV_INLINE
ibool
ulint
rec_offs_comp(
/*==========*/
/* out: TRUE if compact format */
/* out: nonzero if compact format */
const ulint* offsets);/* in: array returned by rec_get_offsets() */
/**********************************************************
Returns TRUE if the nth field of rec is SQL NULL. */
Returns nonzero if the extern bit is set in nth field of rec. */
UNIV_INLINE
ibool
rec_offs_nth_null(
/*==============*/
/* out: TRUE if SQL NULL */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n); /* in: nth field */
/**********************************************************
Returns TRUE if the extern bit is set in nth field of rec. */
UNIV_INLINE
ibool
ulint
rec_offs_nth_extern(
/*================*/
/* out: TRUE if externally stored */
/* out: nonzero if externally stored */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n); /* in: nth field */
/**********************************************************

View file

@ -265,7 +265,7 @@ rec_get_next_offs(
/* out: the page offset of the next chained record, or
0 if none */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
ulint field_value;
@ -312,7 +312,7 @@ void
rec_set_next_offs(
/*==============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint next) /* in: offset of the next record, or 0 if none */
{
ut_ad(rec);
@ -414,7 +414,7 @@ rec_get_n_fields(
{
ut_ad(rec);
ut_ad(index);
if (!index->table->comp) {
if (UNIV_UNLIKELY(!index->table->comp)) {
return(rec_get_n_fields_old(rec));
}
switch (rec_get_status(rec)) {
@ -440,7 +440,7 @@ rec_get_n_owned(
/*============*/
/* out: number of owned records */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
ulint ret;
@ -461,7 +461,7 @@ void
rec_set_n_owned(
/*============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint n_owned) /* in: the number of owned */
{
ut_ad(rec);
@ -480,7 +480,7 @@ rec_get_info_bits(
/*==============*/
/* out: info bits */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
ulint ret;
@ -501,7 +501,7 @@ void
rec_set_info_bits(
/*==============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint bits) /* in: info bits */
{
ut_ad(rec);
@ -537,14 +537,14 @@ rec_get_info_and_status_bits(
/*=========================*/
/* out: info bits */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
ulint bits;
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
& (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
# error "REC_NEW_STATUS_MASK and REC_INFO_BITS_MASK overlap"
#endif
if (comp) {
if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
bits = rec_get_info_bits(rec, TRUE) | rec_get_status(rec);
} else {
bits = rec_get_info_bits(rec, FALSE);
@ -560,7 +560,7 @@ void
rec_set_info_and_status_bits(
/*=========================*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint bits) /* in: info bits */
{
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
@ -578,19 +578,22 @@ rec_set_info_and_status_bits(
/**********************************************************
The following function tells if record is delete marked. */
UNIV_INLINE
ibool
ulint
rec_get_deleted_flag(
/*=================*/
/* out: TRUE if delete marked */
/* out: nonzero if delete marked */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
if (REC_INFO_DELETED_FLAG & rec_get_info_bits(rec, comp)) {
return(TRUE);
if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
return(UNIV_UNLIKELY(rec_get_bit_field_1(rec,
REC_NEW_INFO_BITS, REC_INFO_DELETED_FLAG,
REC_INFO_BITS_SHIFT)));
} else {
return(UNIV_UNLIKELY(rec_get_bit_field_1(rec,
REC_OLD_INFO_BITS, REC_INFO_DELETED_FLAG,
REC_INFO_BITS_SHIFT)));
}
return(FALSE);
}
/**********************************************************
@ -600,24 +603,20 @@ void
rec_set_deleted_flag(
/*=================*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ibool flag) /* in: TRUE if delete marked */
ulint comp, /* in: nonzero=compact page format */
ulint flag) /* in: nonzero if delete marked */
{
ulint old_val;
ulint new_val;
ulint val;
ut_ad(TRUE == 1);
ut_ad(flag <= TRUE);
old_val = rec_get_info_bits(rec, comp);
val = rec_get_info_bits(rec, comp);
if (flag) {
new_val = REC_INFO_DELETED_FLAG | old_val;
val |= REC_INFO_DELETED_FLAG;
} else {
new_val = ~REC_INFO_DELETED_FLAG & old_val;
val &= ~REC_INFO_DELETED_FLAG;
}
rec_set_info_bits(rec, comp, new_val);
rec_set_info_bits(rec, comp, val);
}
/**********************************************************
@ -632,26 +631,6 @@ rec_get_node_ptr_flag(
return(REC_STATUS_NODE_PTR == rec_get_status(rec));
}
/**********************************************************
The following function is used to flag a record as a node pointer. */
UNIV_INLINE
void
rec_set_node_ptr_flag(
/*=================*/
rec_t* rec, /* in: physical record */
ibool flag) /* in: TRUE if the record is a node pointer */
{
ulint status;
ut_ad(flag <= TRUE);
ut_ad(REC_STATUS_NODE_PTR >= rec_get_status(rec));
if (flag) {
status = REC_STATUS_NODE_PTR;
} else {
status = REC_STATUS_ORDINARY;
}
rec_set_status(rec, status);
}
/**********************************************************
The following function is used to get the order number of the record in the
heap of the index page. */
@ -661,7 +640,7 @@ rec_get_heap_no(
/*=============*/
/* out: heap order number */
rec_t* rec, /* in: physical record */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
ulint ret;
@ -682,7 +661,7 @@ void
rec_set_heap_no(
/*=============*/
rec_t* rec, /* in: physical record */
ibool comp, /* in: TRUE=compact page format */
ulint comp, /* in: nonzero=compact page format */
ulint heap_no)/* in: the heap number */
{
ut_ad(heap_no <= REC_MAX_HEAP_NO);
@ -843,7 +822,7 @@ rec_offs_validate(
{
ulint i = rec_offs_n_fields(offsets);
ulint last = ULINT_MAX;
ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0;
ulint comp = *rec_offs_base(offsets) & REC_OFFS_COMPACT;
if (rec) {
ut_ad((ulint) rec == offsets[2]);
@ -926,7 +905,7 @@ rec_get_nth_field(
ut_ad(n < rec_offs_n_fields(offsets));
ut_ad(len);
if (n == 0) {
if (UNIV_UNLIKELY(n == 0)) {
field = rec;
} else {
field = rec + (rec_offs_base(offsets)[n] & REC_OFFS_MASK);
@ -949,43 +928,30 @@ rec_get_nth_field(
Determine if the offsets are for a record in the new
compact format. */
UNIV_INLINE
ibool
ulint
rec_offs_comp(
/*==========*/
/* out: TRUE if compact format */
/* out: nonzero if compact format */
const ulint* offsets)/* in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
return((*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0);
return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
}
/**********************************************************
Returns TRUE if the nth field of rec is SQL NULL. */
Returns nonzero if the extern bit is set in nth field of rec. */
UNIV_INLINE
ibool
rec_offs_nth_null(
/*==============*/
/* out: TRUE if SQL NULL */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n) /* in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
return((rec_offs_base(offsets)[1 + n] & REC_OFFS_SQL_NULL) != 0);
}
/**********************************************************
Returns TRUE if the extern bit is set in nth field of rec. */
UNIV_INLINE
ibool
ulint
rec_offs_nth_extern(
/*================*/
/* out: TRUE if externally stored */
/* out: nonzero if externally stored */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint n) /* in: nth field */
{
ut_ad(rec_offs_validate(NULL, NULL, offsets));
ut_ad(n < rec_offs_n_fields(offsets));
return((rec_offs_base(offsets)[1 + n] & REC_OFFS_EXTERNAL) != 0);
return(UNIV_UNLIKELY(rec_offs_base(offsets)[1 + n]
& REC_OFFS_EXTERNAL));
}
/**********************************************************
@ -1037,7 +1003,7 @@ rec_set_nth_field_extern_bit(
where rec is, or NULL; in the NULL case
we do not write to log about the change */
{
if (index->table->comp) {
if (UNIV_LIKELY(index->table->comp)) {
rec_set_nth_field_extern_bit_new(rec, index, i, val, mtr);
} else {
rec_set_nth_field_extern_bit_old(rec, i, val, mtr);
@ -1048,7 +1014,7 @@ rec_set_nth_field_extern_bit(
Returns the offset of n - 1th field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
value. This function and the 2-byte counterpart are defined here because the
C-compilerwas not able to sum negative and positive constant offsets, and
C-compiler was not able to sum negative and positive constant offsets, and
warned of constant arithmetic overflow within the compiler. */
UNIV_INLINE
ulint
@ -1452,7 +1418,7 @@ rec_get_converted_size(
? dict_index_get_n_unique_in_tree(index) + 1
: dict_index_get_n_fields(index)));
if (index->table->comp) {
if (UNIV_LIKELY(index->table->comp)) {
return(rec_get_converted_size_new(index, dtuple));
}

View file

@ -110,7 +110,7 @@ row_mysql_store_col_in_innobase_format(
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
ibool comp); /* in: TRUE = compact format */
ulint comp); /* in: nonzero=compact format */
/********************************************************************
Handles user errors and lock waits detected by the database engine. */
@ -172,14 +172,6 @@ row_lock_table_autoinc_for_mysql(
row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL
table handle */
/*************************************************************************
Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
lock type LOCK_TABLE_EXP). */
void
row_unlock_tables_for_mysql(
/*========================*/
trx_t* trx); /* in: transaction */
/*************************************************************************
Sets a table lock on the table mentioned in prebuilt. */
int
@ -190,9 +182,10 @@ row_lock_table_for_mysql(
table handle */
dict_table_t* table, /* in: table to lock, or NULL
if prebuilt->table should be
locked as LOCK_TABLE_EXP |
locked as
prebuilt->select_lock_type */
ulint mode); /* in: lock mode of table */
ulint mode); /* in: lock mode of table
(ignored if table==NULL) */
/*************************************************************************
Does an insert for MySQL. */
@ -599,6 +592,8 @@ struct row_prebuilt_struct {
that was decided in ha_innodb.cc,
::store_lock(), ::external_lock(),
etc. */
ulint mysql_prefix_len;/* byte offset of the end of
the last requested column */
ulint mysql_row_len; /* length in bytes of a row in the
MySQL format */
ulint n_rows_fetched; /* number of rows fetched after

View file

@ -75,7 +75,7 @@ open_step(
}
}
if (err != DB_SUCCESS) {
if (UNIV_EXPECT(err, DB_SUCCESS) != DB_SUCCESS) {
/* SQL error detected */
fprintf(stderr, "SQL error %lu\n", (ulong) err);

View file

@ -83,7 +83,7 @@ upd_field_set_field_no(
{
upd_field->field_no = field_no;
if (field_no >= dict_index_get_n_fields(index)) {
if (UNIV_UNLIKELY(field_no >= dict_index_get_n_fields(index))) {
fprintf(stderr,
"InnoDB: Error: trying to access field %lu in ",
(ulong) field_no);

View file

@ -138,7 +138,7 @@ rw_lock_s_lock_low(
#endif /* UNIV_SYNC_DEBUG */
/* Check if the writer field is free */
if (lock->writer == RW_LOCK_NOT_LOCKED) {
if (UNIV_LIKELY(lock->writer == RW_LOCK_NOT_LOCKED)) {
/* Set the shared lock by incrementing the reader count */
lock->reader_count++;
@ -243,7 +243,7 @@ rw_lock_s_lock_func(
mutex_enter(rw_lock_get_mutex(lock));
if (TRUE == rw_lock_s_lock_low(lock, pass, file_name, line)) {
if (UNIV_LIKELY(rw_lock_s_lock_low(lock, pass, file_name, line))) {
mutex_exit(rw_lock_get_mutex(lock));
return; /* Success */
@ -307,21 +307,18 @@ rw_lock_x_lock_func_nowait(
const char* file_name,/* in: file name where lock requested */
ulint line) /* in: line where requested */
{
ibool success = FALSE;
ibool success = FALSE;
os_thread_id_t curr_thread = os_thread_get_curr_id();
mutex_enter(rw_lock_get_mutex(lock));
if ((rw_lock_get_reader_count(lock) == 0)
&& ((rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)
|| ((rw_lock_get_writer(lock) == RW_LOCK_EX)
&& (lock->pass == 0)
&& os_thread_eq(lock->writer_thread,
os_thread_get_curr_id())))) {
if (UNIV_UNLIKELY(rw_lock_get_reader_count(lock) != 0)) {
} else if (UNIV_LIKELY(rw_lock_get_writer(lock)
== RW_LOCK_NOT_LOCKED)) {
rw_lock_set_writer(lock, RW_LOCK_EX);
lock->writer_thread = os_thread_get_curr_id();
lock->writer_count++;
lock->writer_thread = curr_thread;
lock->pass = 0;
relock:
lock->writer_count++;
#ifdef UNIV_SYNC_DEBUG
rw_lock_add_debug_info(lock, 0, RW_LOCK_EX, file_name, line);
@ -331,6 +328,10 @@ rw_lock_x_lock_func_nowait(
lock->last_x_line = line;
success = TRUE;
} else if (rw_lock_get_writer(lock) == RW_LOCK_EX
&& lock->pass == 0
&& os_thread_eq(lock->writer_thread, curr_thread)) {
goto relock;
}
mutex_exit(rw_lock_get_mutex(lock));
@ -361,7 +362,7 @@ rw_lock_s_unlock_func(
/* Reset the shared lock by decrementing the reader count */
ut_a(lock->reader_count > 0);
ut_ad(lock->reader_count > 0);
lock->reader_count--;
#ifdef UNIV_SYNC_DEBUG
@ -371,7 +372,8 @@ rw_lock_s_unlock_func(
/* If there may be waiters and this was the last s-lock,
signal the object */
if (lock->waiters && (lock->reader_count == 0)) {
if (UNIV_UNLIKELY(lock->waiters)
&& lock->reader_count == 0) {
sg = TRUE;
rw_lock_set_waiters(lock, 0);
@ -379,7 +381,7 @@ rw_lock_s_unlock_func(
mutex_exit(mutex);
if (sg == TRUE) {
if (UNIV_UNLIKELY(sg)) {
sync_array_signal_object(sync_primary_wait_array, lock);
}
@ -450,7 +452,8 @@ rw_lock_x_unlock_func(
#endif
/* If there may be waiters, signal the lock */
if (lock->waiters && (lock->writer_count == 0)) {
if (UNIV_UNLIKELY(lock->waiters)
&& lock->writer_count == 0) {
sg = TRUE;
rw_lock_set_waiters(lock, 0);
@ -458,7 +461,7 @@ rw_lock_x_unlock_func(
mutex_exit(&(lock->mutex));
if (sg == TRUE) {
if (UNIV_UNLIKELY(sg)) {
sync_array_signal_object(sync_primary_wait_array, lock);
}

View file

@ -65,7 +65,7 @@ trx_rsegf_get_nth_undo(
ulint n, /* in: index of slot */
mtr_t* mtr) /* in: mtr */
{
if (n >= TRX_RSEG_N_SLOTS) {
if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
fprintf(stderr,
"InnoDB: Error: trying to get slot %lu of rseg\n", (unsigned long) n);
ut_error;
@ -86,7 +86,7 @@ trx_rsegf_set_nth_undo(
ulint page_no,/* in: page number of the undo log segment */
mtr_t* mtr) /* in: mtr */
{
if (n >= TRX_RSEG_N_SLOTS) {
if (UNIV_UNLIKELY(n >= TRX_RSEG_N_SLOTS)) {
fprintf(stderr,
"InnoDB: Error: trying to set slot %lu of rseg\n", (unsigned long) n);
ut_error;

View file

@ -312,6 +312,19 @@ trx_print(
FILE* f, /* in: output stream */
trx_t* trx); /* in: transaction */
#ifndef UNIV_HOTBACKUP
/**************************************************************************
Determines if the currently running transaction has been interrupted. */
ibool
trx_is_interrupted(
/*===============*/
/* out: TRUE if interrupted */
trx_t* trx); /* in: transaction */
#else /* !UNIV_HOTBACKUP */
#define trx_is_interrupted(trx) FALSE
#endif /* !UNIV_HOTBACKUP */
/* Signal to a transaction */
struct trx_sig_struct{
@ -484,13 +497,6 @@ struct trx_struct{
in the lock list trx_locks */
ibool trx_create_lock;/* this is TRUE if we have created a
new lock for a record accessed */
ulint n_lock_table_exp;/* number of explicit table locks
(LOCK TABLES) reserved by the
transaction, stored in trx_locks */
ulint n_lock_table_transactional;
/* number of transactional table locks
(LOCK TABLES..WHERE ENGINE) reserved by
the transaction, stored in trx_locks */
UT_LIST_NODE_T(trx_t)
trx_list; /* list of transactions */
UT_LIST_NODE_T(trx_t)

View file

@ -181,7 +181,7 @@ management to ensure correct alignment for doubles etc. */
/* Another basic type we use is unsigned long integer which should be equal to
the word size of the machine, that is on a 32-bit platform 32 bits, and on a
64-bit platform 64 bits. We also give the printf format for the type as a
macro PRULINT. */
macro ULINTPF. */
#ifdef _WIN64
typedef unsigned __int64 ulint;
@ -243,6 +243,30 @@ contains the sum of the following flag and the locally stored len. */
#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
/* Some macros to improve branch prediction and reduce cache misses */
#if defined(__GNUC__) && (__GNUC__ > 2)
/* Tell the compiler that 'expr' probably evaluates to 'constant'. */
# define UNIV_EXPECT(expr,constant) __builtin_expect(expr, constant)
/* Tell the compiler that a pointer is likely to be NULL */
# define UNIV_LIKELY_NULL(ptr) __builtin_expect((ulint) ptr, 0)
/* Minimize cache-miss latency by moving data at addr into a cache before
it is read. */
# define UNIV_PREFETCH_R(addr) __builtin_prefetch(addr, 0, 3)
/* Minimize cache-miss latency by moving data at addr into a cache before
it is read or written. */
# define UNIV_PREFETCH_RW(addr) __builtin_prefetch(addr, 1, 3)
#else
/* Dummy versions of the macros */
# define UNIV_EXPECT(expr,value) (expr)
# define UNIV_LIKELY_NULL(expr) (expr)
# define UNIV_PREFETCH_R(addr) ((void) 0)
# define UNIV_PREFETCH_RW(addr) ((void) 0)
#endif
/* Tell the compiler that cond is likely to hold */
#define UNIV_LIKELY(cond) UNIV_EXPECT(cond, TRUE)
/* Tell the compiler that cond is unlikely to hold */
#define UNIV_UNLIKELY(cond) UNIV_EXPECT(cond, FALSE)
#include <stdio.h>
#include "ut0dbg.h"
#include "ut0ut.h"

View file

@ -13,74 +13,75 @@ Created 1/30/1994 Heikki Tuuri
#include <stdlib.h>
#include "os0thread.h"
#if defined(__GNUC__) && (__GNUC__ > 2)
# define UT_DBG_FAIL(EXPR) UNIV_UNLIKELY(!((ulint)(EXPR)))
#else
extern ulint ut_dbg_zero; /* This is used to eliminate
compiler warnings */
# define UT_DBG_FAIL(EXPR) !((ulint)(EXPR) + ut_dbg_zero)
#endif
/*****************************************************************
Report a failed assertion. */
void
ut_dbg_assertion_failed(
/*====================*/
const char* expr, /* in: the failed assertion */
const char* file, /* in: source file containing the assertion */
ulint line); /* in: line number of the assertion */
#ifdef __NETWARE__
/* Flag for ignoring further assertion failures.
On NetWare, have a graceful exit rather than a segfault to avoid abends. */
extern ibool panic_shutdown;
/* Abort the execution. */
void ut_dbg_panic(void);
# define UT_DBG_PANIC ut_dbg_panic()
/* Stop threads in ut_a(). */
# define UT_DBG_STOP while (0) /* We do not do this on NetWare */
#else /* __NETWARE__ */
/* Flag for indicating that all threads should stop. This will be set
by ut_dbg_assertion_failed(). */
extern ibool ut_dbg_stop_threads;
/* A null pointer that will be dereferenced to trigger a memory trap */
extern ulint* ut_dbg_null_ptr;
extern const char* ut_dbg_msg_assert_fail;
extern const char* ut_dbg_msg_trap;
extern const char* ut_dbg_msg_stop;
/* Have a graceful exit on NetWare rather than a segfault to avoid abends */
#ifdef __NETWARE__
extern ibool panic_shutdown;
#define ut_a(EXPR) do {\
if (!((ulint)(EXPR) + ut_dbg_zero)) {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__,\
(ulint)__LINE__);\
fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\
fputs(ut_dbg_msg_trap, stderr);\
ut_dbg_stop_threads = TRUE;\
if (ut_dbg_stop_threads) {\
fprintf(stderr, ut_dbg_msg_stop,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
}\
if(!panic_shutdown){\
panic_shutdown = TRUE;\
innobase_shutdown_for_mysql();}\
exit(1);\
}\
} while (0)
#define ut_error do {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
fprintf(stderr, ut_dbg_msg_trap);\
ut_dbg_stop_threads = TRUE;\
if(!panic_shutdown){panic_shutdown = TRUE;\
innobase_shutdown_for_mysql();}\
} while (0)
#else
#define ut_a(EXPR) do {\
if (!((ulint)(EXPR) + ut_dbg_zero)) {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__,\
(ulint)__LINE__);\
fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\
fputs(ut_dbg_msg_trap, stderr);\
ut_dbg_stop_threads = TRUE;\
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\
}\
if (ut_dbg_stop_threads) {\
fprintf(stderr, ut_dbg_msg_stop,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
os_thread_sleep(1000000000);\
}\
/*****************************************************************
Stop a thread after assertion failure. */
void
ut_dbg_stop_thread(
/*===============*/
const char* file,
ulint line);
/* Abort the execution. */
# define UT_DBG_PANIC \
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
/* Stop threads in ut_a(). */
# define UT_DBG_STOP do \
if (UNIV_UNLIKELY(ut_dbg_stop_threads)) { \
ut_dbg_stop_thread(__FILE__, (ulint) __LINE__); \
} while (0)
#endif /* __NETWARE__ */
/* Abort execution if EXPR does not evaluate to nonzero. */
#define ut_a(EXPR) do { \
if (UT_DBG_FAIL(EXPR)) { \
ut_dbg_assertion_failed(#EXPR, \
__FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} \
UT_DBG_STOP; \
} while (0)
#define ut_error do {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
fprintf(stderr, ut_dbg_msg_trap);\
ut_dbg_stop_threads = TRUE;\
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\
/* Abort execution. */
#define ut_error do { \
ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} while (0)
#endif
#ifdef UNIV_DEBUG
#define ut_ad(EXPR) ut_a(EXPR)

View file

@ -207,12 +207,12 @@ ut_fold_binary(
const byte* str, /* in: string of bytes */
ulint len) /* in: length */
{
ulint i;
ulint fold = 0;
const byte* str_end = str + len;
ulint fold = 0;
ut_ad(str);
for (i = 0; i < len; i++) {
while (str < str_end) {
fold = ut_fold_ulint_pair(fold, (ulint)(*str));
str++;

View file

@ -292,7 +292,25 @@ waiting, in its lock queue. Solution: We can copy the locks as gap type
locks, so that also the waiting locks are transformed to granted gap type
locks on the inserted record. */
/* LOCK COMPATIBILITY MATRIX
* IS IX S X AI
* IS + + + - +
* IX + + - - +
* S + - + - -
* X - - - - -
* AI + + - - -
*
* Note that for rows, InnoDB only acquires S or X locks.
* For tables, InnoDB normally acquires IS or IX locks.
* S or X table locks are only acquired for LOCK TABLES.
* Auto-increment (AI) locks are needed because of
* statement-level MySQL binlog.
* See also lock_mode_compatible().
*/
#ifdef UNIV_DEBUG
ibool lock_print_waits = FALSE;
#endif /* UNIV_DEBUG */
/* The lock system */
lock_sys_t* lock_sys = NULL;
@ -348,17 +366,26 @@ static
ibool
lock_deadlock_occurs(
/*=================*/
/* out: TRUE if a deadlock was detected */
/* out: TRUE if a deadlock was detected and we
chose trx as a victim; FALSE if no deadlock, or
there was a deadlock, but we chose other
transaction(s) as victim(s) */
lock_t* lock, /* in: lock the transaction is requesting */
trx_t* trx); /* in: transaction */
/************************************************************************
Looks recursively for a deadlock. */
static
ibool
ulint
lock_deadlock_recursive(
/*====================*/
/* out: TRUE if a deadlock was detected
or the calculation took too long */
/* out: 0 if no deadlock found,
LOCK_VICTIM_IS_START if there was a deadlock
and we chose 'start' as the victim,
LOCK_VICTIM_IS_OTHER if a deadlock
was found and we chose some other trx as a
victim: we must do the search again in this
last case because there may be another
deadlock! */
trx_t* start, /* in: recursion starting point */
trx_t* trx, /* in: a transaction waiting for a lock */
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
@ -492,12 +519,7 @@ lock_clust_rec_cons_read_sees(
trx_id = row_get_rec_trx_id(rec, index, offsets);
if (read_view_sees_trx_id(view, trx_id)) {
return(TRUE);
}
return(FALSE);
return(read_view_sees_trx_id(view, trx_id));
}
/*************************************************************************
@ -1261,7 +1283,6 @@ lock_rec_get_next(
/*==============*/
/* out: next lock, NULL if none exists */
rec_t* rec, /* in: record on a page */
ibool comp, /* in: TRUE=compact page format */
lock_t* lock) /* in: lock */
{
#ifdef UNIV_SYNC_DEBUG
@ -1269,19 +1290,19 @@ lock_rec_get_next(
#endif /* UNIV_SYNC_DEBUG */
ut_ad(lock_get_type(lock) == LOCK_REC);
for (;;) {
lock = lock_rec_get_next_on_page(lock);
if (lock == NULL) {
return(NULL);
}
if (lock_rec_get_nth_bit(lock, rec_get_heap_no(rec, comp))) {
return(lock);
}
if (page_rec_is_comp(rec)) {
do {
lock = lock_rec_get_next_on_page(lock);
} while (lock && !lock_rec_get_nth_bit(lock,
rec_get_heap_no(rec, TRUE)));
} else {
do {
lock = lock_rec_get_next_on_page(lock);
} while (lock && !lock_rec_get_nth_bit(lock,
rec_get_heap_no(rec, FALSE)));
}
return(lock);
}
/*************************************************************************
@ -1294,22 +1315,18 @@ lock_rec_get_first(
rec_t* rec) /* in: record on a page */
{
lock_t* lock;
ibool comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
lock = lock_rec_get_first_on_page(rec);
comp = page_is_comp(buf_frame_align(rec));
if (UNIV_LIKELY_NULL(lock)) {
ulint heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
while (lock) {
if (lock_rec_get_nth_bit(lock, rec_get_heap_no(rec, comp))) {
break;
while (lock && !lock_rec_get_nth_bit(lock, heap_no)) {
lock = lock_rec_get_next_on_page(lock);
}
lock = lock_rec_get_next_on_page(lock);
}
return(lock);
@ -1471,7 +1488,6 @@ lock_rec_has_expl(
for a supremum record we regard this always a gap
type request */
rec_t* rec, /* in: record */
ibool comp, /* in: TRUE=compact page format */
trx_t* trx) /* in: transaction */
{
lock_t* lock;
@ -1501,7 +1517,7 @@ lock_rec_has_expl(
return(lock);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
return(NULL);
@ -1520,7 +1536,6 @@ lock_rec_other_has_expl_req(
ulint wait, /* in: LOCK_WAIT if also waiting locks are
taken into account, or 0 if not */
rec_t* rec, /* in: record to look at */
ibool comp, /* in: TRUE=compact record format */
trx_t* trx) /* in: transaction, or NULL if requests by all
transactions are taken into account */
{
@ -1545,7 +1560,7 @@ lock_rec_other_has_expl_req(
return(lock);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
return(NULL);
@ -1566,13 +1581,11 @@ lock_rec_other_has_conflicting(
trx_t* trx) /* in: our transaction */
{
lock_t* lock;
ibool comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
lock = lock_rec_get_first(rec);
comp = page_is_comp(buf_frame_align(rec));
while (lock) {
if (lock_rec_has_to_wait(trx, mode, lock,
@ -1581,7 +1594,7 @@ lock_rec_other_has_conflicting(
return(lock);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
return(NULL);
@ -1607,7 +1620,7 @@ lock_rec_find_similar_on_page(
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
heap_no = rec_get_heap_no(rec, page_is_comp(buf_frame_align(rec)));
heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
lock = lock_rec_get_first_on_page(rec);
while (lock != NULL) {
@ -1709,6 +1722,8 @@ lock_rec_create(
page_no = buf_frame_get_page_no(page);
heap_no = rec_get_heap_no(rec, page_is_comp(page));
ut_ad(!!page_is_comp(page) == index->table->comp);
/* If rec is the supremum record, then we reset the gap and
LOCK_REC_NOT_GAP bits, as all locks on the supremum are
automatically of the gap type */
@ -1725,7 +1740,7 @@ lock_rec_create(
lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t) + n_bytes);
if (lock == NULL) {
if (UNIV_UNLIKELY(lock == NULL)) {
return(NULL);
}
@ -1826,7 +1841,7 @@ lock_rec_enqueue_waiting(
lock_reset_lock_and_trx_wait(lock);
lock_rec_reset_nth_bit(lock, rec_get_heap_no(rec,
page_is_comp(buf_frame_align(rec))));
page_rec_is_comp(rec)));
return(DB_DEADLOCK);
}
@ -1845,11 +1860,13 @@ lock_rec_enqueue_waiting(
ut_a(que_thr_stop(thr));
#ifdef UNIV_DEBUG
if (lock_print_waits) {
fprintf(stderr, "Lock wait for trx %lu in index ",
(ulong) ut_dulint_get_low(trx->id));
ut_print_name(stderr, trx, index->name);
}
#endif /* UNIV_DEBUG */
return(DB_LOCK_WAIT);
}
@ -1876,7 +1893,6 @@ lock_rec_add_to_queue(
lock_t* lock;
lock_t* similar_lock = NULL;
ulint heap_no;
page_t* page = buf_frame_align(rec);
ibool somebody_waits = FALSE;
#ifdef UNIV_SYNC_DEBUG
@ -1885,11 +1901,11 @@ lock_rec_add_to_queue(
ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP))
|| ((type_mode & LOCK_MODE_MASK) != LOCK_S)
|| !lock_rec_other_has_expl_req(LOCK_X, 0, LOCK_WAIT,
rec, page_is_comp(page), trx));
rec, trx));
ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP))
|| ((type_mode & LOCK_MODE_MASK) != LOCK_X)
|| !lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT,
rec, page_is_comp(page), trx));
rec, trx));
type_mode = type_mode | LOCK_REC;
@ -1898,7 +1914,7 @@ lock_rec_add_to_queue(
try to avoid unnecessary memory consumption of a new record lock
struct for a gap type lock */
if (rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
ut_ad(!(type_mode & LOCK_REC_NOT_GAP));
/* There should never be LOCK_REC_NOT_GAP on a supremum
@ -1909,7 +1925,7 @@ lock_rec_add_to_queue(
/* Look for a waiting lock request on the same record or on a gap */
heap_no = rec_get_heap_no(rec, page_is_comp(page));
heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
lock = lock_rec_get_first_on_page(rec);
while (lock != NULL) {
@ -1984,7 +2000,7 @@ lock_rec_lock_fast(
|| mode - (LOCK_MODE_MASK & mode) == 0
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
heap_no = rec_get_heap_no(rec, page_is_comp(buf_frame_align(rec)));
heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
lock = lock_rec_get_first_on_page(rec);
@ -2065,8 +2081,7 @@ lock_rec_lock_slow(
trx = thr_get_trx(thr);
if (lock_rec_has_expl(mode, rec,
page_is_comp(buf_frame_align(rec)), trx)) {
if (lock_rec_has_expl(mode, rec, trx)) {
/* The trx already has a strong enough lock on rec: do
nothing */
@ -2207,16 +2222,14 @@ lock_grant(
release it at the end of the SQL statement */
lock->trx->auto_inc_lock = lock;
} else if (lock_get_type(lock) == LOCK_TABLE_EXP ||
lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
ut_a(lock_get_mode(lock) == LOCK_S
|| lock_get_mode(lock) == LOCK_X);
}
}
#ifdef UNIV_DEBUG
if (lock_print_waits) {
fprintf(stderr, "Lock wait for trx %lu ends\n",
(ulong) ut_dulint_get_low(lock->trx->id));
}
#endif /* UNIV_DEBUG */
/* If we are resolving a deadlock by choosing another transaction
as a victim, then our original transaction may not be in the
@ -2383,14 +2396,12 @@ lock_rec_reset_and_release_wait(
{
lock_t* lock;
ulint heap_no;
ibool comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
comp = page_is_comp(buf_frame_align(rec));
heap_no = rec_get_heap_no(rec, comp);
heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
lock = lock_rec_get_first(rec);
@ -2401,7 +2412,7 @@ lock_rec_reset_and_release_wait(
lock_rec_reset_nth_bit(lock, heap_no);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
}
@ -2419,13 +2430,11 @@ lock_rec_inherit_to_gap(
the locks on this record */
{
lock_t* lock;
ibool comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
lock = lock_rec_get_first(rec);
comp = page_is_comp(buf_frame_align(rec));
while (lock != NULL) {
if (!lock_rec_get_insert_intention(lock)) {
@ -2435,7 +2444,7 @@ lock_rec_inherit_to_gap(
heir, lock->index, lock->trx);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
}
@ -2452,13 +2461,11 @@ lock_rec_inherit_to_gap_if_gap_lock(
the locks on this record */
{
lock_t* lock;
ibool comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
lock = lock_rec_get_first(rec);
comp = page_is_comp(buf_frame_align(rec));
while (lock != NULL) {
if (!lock_rec_get_insert_intention(lock)
@ -2470,7 +2477,7 @@ lock_rec_inherit_to_gap_if_gap_lock(
heir, lock->index, lock->trx);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
}
@ -2484,7 +2491,7 @@ lock_rec_move(
rec_t* receiver, /* in: record which gets locks; this record
must have no lock requests on it! */
rec_t* donator, /* in: record which gives locks */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
lock_t* lock;
ulint heap_no;
@ -2514,7 +2521,7 @@ lock_rec_move(
lock_rec_add_to_queue(type_mode, receiver, lock->index,
lock->trx);
lock = lock_rec_get_next(donator, comp, lock);
lock = lock_rec_get_next(donator, lock);
}
ut_ad(lock_rec_get_first(donator) == NULL);
@ -2540,7 +2547,7 @@ lock_move_reorganize_page(
UT_LIST_BASE_NODE_T(lock_t) old_locks;
mem_heap_t* heap = NULL;
rec_t* sup;
ibool comp;
ulint comp;
lock_mutex_enter_kernel();
@ -2659,8 +2666,9 @@ lock_move_rec_list_end(
ulint heap_no;
rec_t* sup;
ulint type_mode;
ibool comp;
ulint comp;
ut_ad(page == buf_frame_align(rec));
lock_mutex_enter_kernel();
/* Note: when we move locks from record to record, waiting locks
@ -2745,7 +2753,7 @@ lock_move_rec_list_start(
page_cur_t cur2;
ulint heap_no;
ulint type_mode;
ibool comp;
ulint comp;
ut_a(new_page);
@ -2754,6 +2762,7 @@ lock_move_rec_list_start(
lock = lock_rec_get_first_on_page(page);
comp = page_is_comp(page);
ut_ad(comp == page_is_comp(new_page));
ut_ad(page == buf_frame_align(rec));
while (lock != NULL) {
@ -2812,7 +2821,7 @@ lock_update_split_right(
page_t* right_page, /* in: right page */
page_t* left_page) /* in: left page */
{
ibool comp;
ulint comp;
lock_mutex_enter_kernel();
comp = page_is_comp(left_page);
ut_ad(comp == page_is_comp(right_page));
@ -2875,7 +2884,7 @@ lock_update_root_raise(
page_t* new_page, /* in: index page to which copied */
page_t* root) /* in: root page */
{
ibool comp;
ulint comp;
lock_mutex_enter_kernel();
comp = page_is_comp(root);
ut_ad(comp == page_is_comp(new_page));
@ -2898,7 +2907,7 @@ lock_update_copy_and_discard(
page_t* new_page, /* in: index page to which copied */
page_t* page) /* in: index page; NOT the root! */
{
ibool comp;
ulint comp;
lock_mutex_enter_kernel();
comp = page_is_comp(page);
ut_ad(comp == page_is_comp(new_page));
@ -2945,31 +2954,34 @@ lock_update_merge_left(
page_t* right_page) /* in: merged index page which will be
discarded */
{
ibool comp;
rec_t* left_next_rec;
rec_t* left_supremum;
ulint comp;
lock_mutex_enter_kernel();
comp = page_is_comp(left_page);
ut_ad(comp == page_is_comp(right_page));
ut_ad(left_page == buf_frame_align(orig_pred));
if (page_rec_get_next(orig_pred) != page_get_supremum_rec(left_page)) {
left_next_rec = page_rec_get_next(orig_pred);
left_supremum = page_get_supremum_rec(left_page);
if (UNIV_LIKELY(left_next_rec != left_supremum)) {
/* Inherit the locks on the supremum of the left page to the
first record which was moved from the right page */
lock_rec_inherit_to_gap(page_rec_get_next(orig_pred),
page_get_supremum_rec(left_page));
lock_rec_inherit_to_gap(left_next_rec, left_supremum);
/* Reset the locks on the supremum of the left page,
releasing waiting transactions */
lock_rec_reset_and_release_wait(page_get_supremum_rec(
left_page));
lock_rec_reset_and_release_wait(left_supremum);
}
/* Move the locks from the supremum of right page to the supremum
of the left page */
lock_rec_move(page_get_supremum_rec(left_page),
page_get_supremum_rec(right_page), comp);
lock_rec_move(left_supremum, page_get_supremum_rec(right_page), comp);
lock_rec_free_all_from_discard_page(right_page);
@ -3028,7 +3040,7 @@ lock_update_discard(
lock_rec_reset_and_release_wait(rec);
if (rec == page_get_supremum_rec(page)) {
if (page_rec_is_supremum(rec)) {
break;
}
@ -3091,19 +3103,16 @@ actual record is being moved. */
void
lock_rec_store_on_page_infimum(
/*===========================*/
page_t* page, /* in: page containing the record */
rec_t* rec) /* in: record whose lock state is stored
on the infimum record of the same page; lock
bits are reset on the record */
{
page_t* page;
ibool comp;
page = buf_frame_align(rec);
comp = page_is_comp(page);
ut_ad(page == buf_frame_align(rec));
lock_mutex_enter_kernel();
lock_rec_move(page_get_infimum_rec(page), rec, comp);
lock_rec_move(page_get_infimum_rec(page), rec, page_is_comp(page));
lock_mutex_exit_kernel();
}
@ -3120,10 +3129,10 @@ lock_rec_restore_from_page_infimum(
whose infimum stored the lock state; lock bits are
reset on the infimum */
{
ibool comp;
ulint comp;
lock_mutex_enter_kernel();
comp = page_is_comp(page);
ut_ad(comp == page_is_comp(buf_frame_align(rec)));
ut_ad(!comp == !page_rec_is_comp(rec));
lock_rec_move(rec, page_get_infimum_rec(page), comp);
@ -3316,11 +3325,11 @@ lock_deadlock_recursive(
} else {
lock_table_print(ef, start->wait_lock);
}
#ifdef UNIV_DEBUG
if (lock_print_waits) {
fputs("Deadlock detected\n", stderr);
}
#endif /* UNIV_DEBUG */
if (ut_dulint_cmp(wait_lock->trx->undo_no,
start->undo_no) >= 0) {
/* Our recursion starting point
@ -3418,14 +3427,6 @@ lock_table_create(
lock->type_mode = type_mode | LOCK_TABLE;
lock->trx = trx;
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
lock->trx->n_lock_table_exp++;
}
if (lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
lock->trx->n_lock_table_transactional++;
}
lock->un_member.tab_lock.table = table;
UT_LIST_ADD_LAST(un_member.tab_lock.locks, table->locks, lock);
@ -3462,14 +3463,6 @@ lock_table_remove_low(
trx->auto_inc_lock = NULL;
}
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
trx->n_lock_table_exp--;
}
if (lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
trx->n_lock_table_transactional--;
}
UT_LIST_REMOVE(trx_locks, trx->trx_locks, lock);
UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock);
}
@ -3600,10 +3593,7 @@ lock_table(
/* out: DB_SUCCESS, DB_LOCK_WAIT,
DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set,
does nothing;
if LOCK_TABLE_EXP|LOCK_TABLE_TRANSACTIONAL
bits are set,
creates an explicit table lock */
does nothing */
dict_table_t* table, /* in: database table in dictionary cache */
ulint mode, /* in: lock mode */
que_thr_t* thr) /* in: query thread */
@ -3618,8 +3608,7 @@ lock_table(
return(DB_SUCCESS);
}
ut_a(flags == 0 || flags == LOCK_TABLE_EXP ||
flags == LOCK_TABLE_TRANSACTIONAL);
ut_a(flags == 0);
trx = thr_get_trx(thr);
@ -3732,9 +3721,7 @@ lock_table_dequeue(
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
ut_a(lock_get_type(in_lock) == LOCK_TABLE ||
lock_get_type(in_lock) == LOCK_TABLE_EXP ||
lock_get_type(in_lock) == LOCK_TABLE_TRANSACTIONAL);
ut_a(lock_get_type(in_lock) == LOCK_TABLE);
lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, in_lock);
@ -3838,12 +3825,6 @@ lock_release_off_kernel(
}
lock_table_dequeue(lock);
if (lock_get_type(lock) == LOCK_TABLE_EXP ||
lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
ut_a(lock_get_mode(lock) == LOCK_S
|| lock_get_mode(lock) == LOCK_X);
}
}
if (count == LOCK_RELEASE_KERNEL_INTERVAL) {
@ -3863,74 +3844,6 @@ lock_release_off_kernel(
mem_heap_empty(trx->lock_heap);
ut_a(trx->auto_inc_lock == NULL);
ut_a(trx->n_lock_table_exp == 0);
ut_a(trx->n_lock_table_transactional == 0);
}
/*************************************************************************
Releases table locks explicitly requested with LOCK TABLES (indicated by
lock type LOCK_TABLE_EXP), and releases possible other transactions waiting
because of these locks. */
void
lock_release_tables_off_kernel(
/*===========================*/
trx_t* trx) /* in: transaction */
{
dict_table_t* table;
ulint count;
lock_t* lock;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
lock = UT_LIST_GET_LAST(trx->trx_locks);
count = 0;
while (lock != NULL) {
count++;
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
ut_a(lock_get_mode(lock) == LOCK_S
|| lock_get_mode(lock) == LOCK_X);
if (trx->insert_undo || trx->update_undo) {
/* The trx may have modified the table.
We block the use of the MySQL query
cache for all currently active
transactions. */
table = lock->un_member.tab_lock.table;
table->query_cache_inv_trx_id =
trx_sys->max_trx_id;
}
lock_table_dequeue(lock);
lock = UT_LIST_GET_LAST(trx->trx_locks);
continue;
}
if (count == LOCK_RELEASE_KERNEL_INTERVAL) {
/* Release the kernel mutex for a while, so that we
do not monopolize it */
lock_mutex_exit_kernel();
lock_mutex_enter_kernel();
count = 0;
}
lock = UT_LIST_GET_PREV(trx_locks, lock);
}
ut_a(trx->n_lock_table_exp == 0);
ut_a(trx->n_lock_table_transactional == 0);
}
/*************************************************************************
@ -4043,15 +3956,7 @@ lock_table_print(
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
ut_a(lock_get_type(lock) == LOCK_TABLE ||
lock_get_type(lock) == LOCK_TABLE_EXP ||
lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL);
if (lock_get_type(lock) == LOCK_TABLE_EXP) {
fputs("EXPLICIT ", file);
} else if (lock_get_type(lock) == LOCK_TABLE_TRANSACTIONAL) {
fputs("TRANSACTIONAL ", file);
}
ut_a(lock_get_type(lock) == LOCK_TABLE);
fputs("TABLE LOCK table ", file);
ut_print_name(file, lock->trx, lock->un_member.tab_lock.table->name);
@ -4187,7 +4092,7 @@ lock_rec_print(
}
mtr_commit(&mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -4483,15 +4388,14 @@ lock_rec_queue_validate(
{
trx_t* impl_trx;
lock_t* lock;
ibool comp;
ut_a(rec);
ut_ad(rec_offs_validate(rec, index, offsets));
comp = page_is_comp(buf_frame_align(rec));
ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
lock_mutex_enter_kernel();
if (page_rec_is_supremum(rec) || page_rec_is_infimum(rec)) {
if (!page_rec_is_user_rec(rec)) {
lock = lock_rec_get_first(rec);
@ -4511,7 +4415,7 @@ lock_rec_queue_validate(
ut_a(lock->index == index);
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
lock_mutex_exit_kernel();
@ -4524,10 +4428,10 @@ lock_rec_queue_validate(
impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets);
if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
LOCK_WAIT, rec, comp, impl_trx)) {
LOCK_WAIT, rec, impl_trx)) {
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
comp, impl_trx));
impl_trx));
}
}
@ -4541,10 +4445,10 @@ lock_rec_queue_validate(
rec, index, offsets);
if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0,
LOCK_WAIT, rec, comp, impl_trx)) {
LOCK_WAIT, rec, impl_trx)) {
ut_a(lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP,
rec, comp, impl_trx));
rec, impl_trx));
}
}
@ -4561,21 +4465,23 @@ lock_rec_queue_validate(
}
if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) {
ulint mode;
if (lock_get_mode(lock) == LOCK_S) {
ut_a(!lock_rec_other_has_expl_req(LOCK_X,
0, 0, rec, comp, lock->trx));
mode = LOCK_X;
} else {
ut_a(!lock_rec_other_has_expl_req(LOCK_S,
0, 0, rec, comp, lock->trx));
mode = LOCK_S;
}
ut_a(!lock_rec_other_has_expl_req(mode,
0, 0, rec, lock->trx));
} else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) {
ut_a(lock_rec_has_to_wait_in_queue(lock));
}
lock = lock_rec_get_next(rec, comp, lock);
lock = lock_rec_get_next(rec, lock);
}
lock_mutex_exit_kernel();
@ -4673,7 +4579,7 @@ function_exit:
mtr_commit(&mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(TRUE);
@ -4859,7 +4765,7 @@ lock_rec_insert_check_and_lock(
offsets = rec_get_offsets(next_rec, index, offsets_,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(next_rec, index, offsets));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -4887,7 +4793,7 @@ lock_rec_convert_impl_to_expl(
#endif /* UNIV_SYNC_DEBUG */
ut_ad(page_rec_is_user_rec(rec));
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(page_is_comp(buf_frame_align(rec)) == index->table->comp);
ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
if (index->type & DICT_CLUSTERED) {
impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets);
@ -4901,7 +4807,7 @@ lock_rec_convert_impl_to_expl(
record, set one for it */
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec,
index->table->comp, impl_trx)) {
impl_trx)) {
lock_rec_add_to_queue(LOCK_REC | LOCK_X
| LOCK_REC_NOT_GAP, rec, index,
@ -5008,7 +4914,7 @@ lock_sec_rec_modify_check_and_lock(
offsets = rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap);
ut_ad(lock_rec_queue_validate(rec, index, offsets));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}

View file

@ -57,10 +57,11 @@ ulint log_fsp_current_free_limit = 0;
/* Global log system variable */
log_t* log_sys = NULL;
#ifdef UNIV_DEBUG
ibool log_do_write = TRUE;
ibool log_debug_writes = FALSE;
#endif /* UNIV_DEBUG */
/* These control how often we print warnings if the last checkpoint is too
old */
@ -974,22 +975,24 @@ log_group_check_flush_completion(
#endif /* UNIV_SYNC_DEBUG */
if (!log_sys->one_flushed && group->n_pending_writes == 0) {
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Log flushed first to group %lu\n", (ulong) group->id);
}
#endif /* UNIV_DEBUG */
log_sys->written_to_some_lsn = log_sys->write_lsn;
log_sys->one_flushed = TRUE;
return(LOG_UNLOCK_NONE_FLUSHED_LOCK);
}
#ifdef UNIV_DEBUG
if (log_debug_writes && (group->n_pending_writes == 0)) {
fprintf(stderr, "Log flushed to group %lu\n", (ulong) group->id);
}
#endif /* UNIV_DEBUG */
return(0);
}
@ -1066,12 +1069,13 @@ log_io_complete(
fil_flush(group->space_id);
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Checkpoint info written to group %lu\n",
group->id);
}
#endif /* UNIV_DEBUG */
log_io_complete_checkpoint();
return;
@ -1133,12 +1137,13 @@ log_group_file_header_flush(
dest_offset = nth_file * group->file_size;
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Writing log file header to group %lu file %lu\n",
(ulong) group->id, (ulong) nth_file);
}
#endif /* UNIV_DEBUG */
if (log_do_write) {
log_sys->n_log_ios++;
@ -1226,7 +1231,8 @@ loop:
} else {
write_len = len;
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
@ -1250,7 +1256,7 @@ loop:
+ i * OS_FILE_LOG_BLOCK_SIZE));
}
}
#endif /* UNIV_DEBUG */
/* Calculate the checksums for each log block and write them to
the trailer fields of the log blocks */
@ -1384,6 +1390,7 @@ loop:
return;
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Writing log from %lu %lu up to lsn %lu %lu\n",
@ -1392,7 +1399,7 @@ loop:
(ulong) ut_dulint_get_high(log_sys->lsn),
(ulong) ut_dulint_get_low(log_sys->lsn));
}
#endif /* UNIV_DEBUG */
log_sys->n_pending_writes++;
group = UT_LIST_GET_FIRST(log_sys->log_groups);
@ -1961,12 +1968,14 @@ log_checkpoint(
log_sys->next_checkpoint_lsn = oldest_lsn;
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr, "Making checkpoint no %lu at lsn %lu %lu\n",
(ulong) ut_dulint_get_low(log_sys->next_checkpoint_no),
(ulong) ut_dulint_get_high(oldest_lsn),
(ulong) ut_dulint_get_low(oldest_lsn));
}
#endif /* UNIV_DEBUG */
log_groups_write_checkpoint_info();
@ -2029,8 +2038,6 @@ log_checkpoint_margin(void)
ulint checkpoint_age;
ulint advance;
dulint oldest_lsn;
dulint new_oldest;
ibool do_preflush;
ibool sync;
ibool checkpoint_sync;
ibool do_checkpoint;
@ -2038,7 +2045,6 @@ log_checkpoint_margin(void)
loop:
sync = FALSE;
checkpoint_sync = FALSE;
do_preflush = FALSE;
do_checkpoint = FALSE;
mutex_enter(&(log->mutex));
@ -2058,21 +2064,13 @@ loop:
/* A flush is urgent: we have to do a synchronous preflush */
sync = TRUE;
advance = 2 * (age - log->max_modified_age_sync);
new_oldest = ut_dulint_add(oldest_lsn, advance);
do_preflush = TRUE;
advance = 2 * (age - log->max_modified_age_async);
} else if (age > log->max_modified_age_async) {
/* A flush is not urgent: we do an asynchronous preflush */
advance = age - log->max_modified_age_async;
new_oldest = ut_dulint_add(oldest_lsn, advance);
do_preflush = TRUE;
} else {
advance = 0;
}
checkpoint_age = ut_dulint_minus(log->lsn, log->last_checkpoint_lsn);
@ -2096,7 +2094,9 @@ loop:
mutex_exit(&(log->mutex));
if (do_preflush) {
if (advance) {
dulint new_oldest = ut_dulint_add(oldest_lsn, advance);
success = log_preflush_pool_modified_pages(new_oldest, sync);
/* If the flush succeeded, this thread has done its part
@ -2347,9 +2347,11 @@ loop:
exit(1);
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr, "Created archive file %s\n", name);
}
#endif /* UNIV_DEBUG */
ret = os_file_close(file_handle);
@ -2375,7 +2377,8 @@ loop:
len = group->file_size - (next_offset % group->file_size);
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Archiving starting at lsn %lu %lu, len %lu to group %lu\n",
@ -2383,6 +2386,7 @@ loop:
(ulong) ut_dulint_get_low(start_lsn),
(ulong) len, (ulong) group->id);
}
#endif /* UNIV_DEBUG */
log_sys->n_pending_archive_ios++;
@ -2473,11 +2477,13 @@ log_archive_write_complete_groups(void)
trunc_files = n_files - 1;
}
#ifdef UNIV_DEBUG
if (log_debug_writes && trunc_files) {
fprintf(stderr,
"Complete file(s) archived to group %lu\n",
(ulong) group->id);
}
#endif /* UNIV_DEBUG */
/* Calculate the archive file space start lsn */
start_lsn = ut_dulint_subtract(log_sys->next_archived_lsn,
@ -2500,9 +2506,11 @@ log_archive_write_complete_groups(void)
fil_space_truncate_start(group->archive_space_id,
trunc_files * group->file_size);
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fputs("Archiving writes completed\n", stderr);
}
#endif /* UNIV_DEBUG */
}
/**********************************************************
@ -2519,9 +2527,11 @@ log_archive_check_completion_low(void)
if (log_sys->n_pending_archive_ios == 0
&& log_sys->archiving_phase == LOG_ARCHIVE_READ) {
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fputs("Archiving read completed\n", stderr);
}
#endif /* UNIV_DEBUG */
/* Archive buffer has now been read in: start archive writes */
@ -2665,6 +2675,7 @@ loop:
log_sys->next_archived_lsn = limit_lsn;
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Archiving from lsn %lu %lu to lsn %lu %lu\n",
@ -2673,6 +2684,7 @@ loop:
(ulong) ut_dulint_get_high(limit_lsn),
(ulong) ut_dulint_get_low(limit_lsn));
}
#endif /* UNIV_DEBUG */
/* Read the log segment to the archive buffer */
@ -2775,12 +2787,14 @@ log_archive_close_groups(
group->archived_file_no += 2;
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"Incrementing arch file no to %lu in log group %lu\n",
(ulong) group->archived_file_no + 2,
(ulong) group->id);
}
#endif /* UNIV_DEBUG */
}
}

View file

@ -489,6 +489,7 @@ recv_find_max_checkpoint(
log_group_read_checkpoint_info(group, field);
if (!recv_check_cp_is_consistent(buf)) {
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Checkpoint in group %lu at %lu invalid, %lu\n",
@ -498,7 +499,7 @@ recv_find_max_checkpoint(
+ LOG_CHECKPOINT_CHECKSUM_1));
}
#endif /* UNIV_DEBUG */
goto not_consistent;
}
@ -511,13 +512,15 @@ recv_find_max_checkpoint(
checkpoint_no =
mach_read_from_8(buf + LOG_CHECKPOINT_NO);
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Checkpoint number %lu found in group %lu\n",
(ulong) ut_dulint_get_low(checkpoint_no),
(ulong) group->id);
}
#endif /* UNIV_DEBUG */
if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {
*max_group = group;
*max_field = field;
@ -540,7 +543,7 @@ recv_find_max_checkpoint(
"InnoDB: to create the InnoDB data files, but log file creation failed.\n"
"InnoDB: If that is the case, please refer to\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/Error_creating_InnoDB.html\n");
*max_field = 0;
return(DB_ERROR);
}
@ -765,6 +768,7 @@ recv_parse_or_apply_log_rec_body(
case MLOG_REC_INSERT: case MLOG_COMP_REC_INSERT:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_REC_INSERT, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = page_cur_parse_insert_rec(FALSE, ptr, end_ptr,
index, page, mtr);
}
@ -772,20 +776,27 @@ recv_parse_or_apply_log_rec_body(
case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_REC_CLUST_DELETE_MARK, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = btr_cur_parse_del_mark_set_clust_rec(ptr,
end_ptr, index, page);
}
break;
case MLOG_REC_SEC_DELETE_MARK: case MLOG_COMP_REC_SEC_DELETE_MARK:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_REC_SEC_DELETE_MARK, &index))) {
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr,
index, page);
case MLOG_COMP_REC_SEC_DELETE_MARK:
/* This log record type is obsolete, but we process it for
backward compatibility with MySQL 5.0.3 and 5.0.4. */
ut_a(!page || page_is_comp(page));
ptr = mlog_parse_index(ptr, end_ptr, TRUE, &index);
if (!ptr) {
break;
}
/* Fall through */
case MLOG_REC_SEC_DELETE_MARK:
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr, page);
break;
case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_REC_UPDATE_IN_PLACE, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = btr_cur_parse_update_in_place(ptr, end_ptr,
page, index);
}
@ -795,6 +806,7 @@ recv_parse_or_apply_log_rec_body(
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_LIST_END_DELETE
|| type == MLOG_COMP_LIST_START_DELETE, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = page_parse_delete_rec_list(type, ptr, end_ptr,
index, page, mtr);
}
@ -802,6 +814,7 @@ recv_parse_or_apply_log_rec_body(
case MLOG_LIST_END_COPY_CREATED: case MLOG_COMP_LIST_END_COPY_CREATED:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_LIST_END_COPY_CREATED, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = page_parse_copy_rec_list_to_created_page(ptr,
end_ptr, index, page, mtr);
}
@ -809,6 +822,7 @@ recv_parse_or_apply_log_rec_body(
case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_PAGE_REORGANIZE, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = btr_parse_page_reorganize(ptr, end_ptr, index,
page, mtr);
}
@ -841,6 +855,7 @@ recv_parse_or_apply_log_rec_body(
case MLOG_REC_DELETE: case MLOG_COMP_REC_DELETE:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
type == MLOG_COMP_REC_DELETE, &index))) {
ut_a(!page||!!page_is_comp(page)==index->table->comp);
ptr = page_cur_parse_delete_rec(ptr, end_ptr,
index, page, mtr);
}
@ -1186,6 +1201,7 @@ recv_recover_page(
start_lsn = recv->start_lsn;
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Applying log rec type %lu len %lu to space %lu page no %lu\n",
@ -1193,6 +1209,7 @@ recv_recover_page(
(ulong) recv_addr->space,
(ulong) recv_addr->page_no);
}
#endif /* UNIV_DEBUG */
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len, page, &mtr);
@ -1801,25 +1818,25 @@ recv_parse_log_rec(
new_ptr = mlog_parse_initial_log_record(ptr, end_ptr, type, space,
page_no);
if (!new_ptr) {
*body = new_ptr;
if (UNIV_UNLIKELY(!new_ptr)) {
return(0);
}
/* Check that page_no is sensible */
if (*page_no > 0x8FFFFFFFUL) {
if (UNIV_UNLIKELY(*page_no > 0x8FFFFFFFUL)) {
recv_sys->found_corrupt_log = TRUE;
return(0);
}
*body = new_ptr;
new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
NULL, NULL);
if (new_ptr == NULL) {
if (UNIV_UNLIKELY(new_ptr == NULL)) {
return(0);
}
@ -2013,12 +2030,14 @@ loop:
recv_sys->recovered_offset += len;
recv_sys->recovered_lsn = new_recovered_lsn;
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Parsed a single log rec type %lu len %lu space %lu page no %lu\n",
(ulong) type, (ulong) len, (ulong) space,
(ulong) page_no);
}
#endif /* UNIV_DEBUG */
if (type == MLOG_DUMMY_RECORD) {
/* Do nothing */
@ -2101,13 +2120,15 @@ loop:
body, ptr + len);
#endif /* UNIV_LOG_REPLICATE */
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Parsed a multi log rec type %lu len %lu space %lu page no %lu\n",
(ulong) type, (ulong) len, (ulong) space,
(ulong) page_no);
}
#endif /* UNIV_DEBUG */
total_len += len;
n_recs++;
@ -2514,6 +2535,7 @@ recv_group_scan_log_recs(
start_lsn = end_lsn;
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Scanned group %lu up to log sequence number %lu %lu\n",
@ -2521,6 +2543,7 @@ recv_group_scan_log_recs(
(ulong) ut_dulint_get_high(*group_scanned_lsn),
(ulong) ut_dulint_get_low(*group_scanned_lsn));
}
#endif /* UNIV_DEBUG */
}
/************************************************************
@ -2906,10 +2929,12 @@ recv_recovery_from_checkpoint_finish(void)
recv_apply_hashed_log_recs(TRUE);
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Log records applied to the database\n");
}
#endif /* UNIV_DEBUG */
if (recv_needed_recovery) {
trx_sys_print_mysql_master_log_pos();
@ -3246,6 +3271,7 @@ ask_again:
break;
}
#ifdef UNIV_DEBUG
if (log_debug_writes) {
fprintf(stderr,
"InnoDB: Archive read starting at lsn %lu %lu, len %lu from file %s\n",
@ -3253,6 +3279,7 @@ ask_again:
(ulong) ut_dulint_get_low(start_lsn),
(ulong) len, name);
}
#endif /* UNIV_DEBUG */
fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE,
group->archive_space_id, read_offset / UNIV_PAGE_SIZE,

View file

@ -15,6 +15,7 @@ Created 12/7/1995 Heikki Tuuri
#include "buf0buf.h"
#include "dict0boot.h"
#include "log0recv.h"
#include "page0page.h"
/************************************************************
Catenates n bytes to the mtr log. */
@ -22,9 +23,9 @@ Catenates n bytes to the mtr log. */
void
mlog_catenate_string(
/*=================*/
mtr_t* mtr, /* in: mtr */
byte* str, /* in: string to write */
ulint len) /* in: string length */
mtr_t* mtr, /* in: mtr */
const byte* str, /* in: string to write */
ulint len) /* in: string length */
{
dyn_array_t* mlog;
@ -301,14 +302,15 @@ corresponding log record to the mini-transaction log. */
void
mlog_write_string(
/*==============*/
byte* ptr, /* in: pointer where to write */
byte* str, /* in: string to write */
ulint len, /* in: string length */
mtr_t* mtr) /* in: mini-transaction handle */
byte* ptr, /* in: pointer where to write */
const byte* str, /* in: string to write */
ulint len, /* in: string length */
mtr_t* mtr) /* in: mini-transaction handle */
{
byte* log_ptr;
if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) {
if (UNIV_UNLIKELY(ptr < buf_pool->frame_zero)
|| UNIV_UNLIKELY(ptr >= buf_pool->high_end)) {
fprintf(stderr,
"InnoDB: Error: trying to write to a stray memory location %p\n", ptr);
ut_error;
@ -405,7 +407,9 @@ mlog_open_and_write_index(
const byte* log_start;
const byte* log_end;
if (!index->table->comp) {
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
if (!page_rec_is_comp(rec)) {
log_start = log_ptr = mlog_open(mtr, 11 + size);
if (!log_ptr) {
return(NULL); /* logging is disabled */
@ -498,6 +502,8 @@ mlog_parse_index(
dict_table_t* table;
dict_index_t* ind;
ut_ad(comp == FALSE || comp == TRUE);
if (comp) {
if (end_ptr < ptr + 4) {
return(NULL);

View file

@ -48,16 +48,11 @@ mtr_memo_slot_release(
object = slot->object;
type = slot->type;
if (object != NULL) {
if (UNIV_LIKELY(object != NULL)) {
if (type <= MTR_MEMO_BUF_FIX) {
buf_page_release((buf_block_t*)object, type, mtr);
} else if (type == MTR_MEMO_S_LOCK) {
rw_lock_s_unlock((rw_lock_t*)object);
#ifndef UNIV_DEBUG
} else {
rw_lock_x_unlock((rw_lock_t*)object);
}
#endif
#ifdef UNIV_DEBUG
} else if (type == MTR_MEMO_X_LOCK) {
rw_lock_x_unlock((rw_lock_t*)object);
@ -65,8 +60,11 @@ mtr_memo_slot_release(
ut_ad(type == MTR_MEMO_MODIFY);
ut_ad(mtr_memo_contains(mtr, object,
MTR_MEMO_PAGE_X_FIX));
}
#else
} else {
rw_lock_x_unlock((rw_lock_t*)object);
#endif
}
}
slot->object = NULL;

View file

@ -83,7 +83,7 @@ struct os_aio_slot_struct{
made and only the slot message
needs to be passed to the caller
of os_aio_simulated_handle */
void* message1; /* message which is given by the */
fil_node_t* message1; /* message which is given by the */
void* message2; /* the requester of an aio operation
and which can be used to identify
which pending aio operation was
@ -133,17 +133,17 @@ os_event_t* os_aio_segment_wait_events = NULL;
/* The aio arrays for non-ibuf i/o and ibuf i/o, as well as sync aio. These
are NULL when the module has not yet been initialized. */
os_aio_array_t* os_aio_read_array = NULL;
os_aio_array_t* os_aio_write_array = NULL;
os_aio_array_t* os_aio_ibuf_array = NULL;
os_aio_array_t* os_aio_log_array = NULL;
os_aio_array_t* os_aio_sync_array = NULL;
static os_aio_array_t* os_aio_read_array = NULL;
static os_aio_array_t* os_aio_write_array = NULL;
static os_aio_array_t* os_aio_ibuf_array = NULL;
static os_aio_array_t* os_aio_log_array = NULL;
static os_aio_array_t* os_aio_sync_array = NULL;
ulint os_aio_n_segments = ULINT_UNDEFINED;
static ulint os_aio_n_segments = ULINT_UNDEFINED;
/* If the following is TRUE, read i/o handler threads try to
wait until a batch of new read requests have been posted */
ibool os_aio_recommend_sleep_for_read_threads = FALSE;
static ibool os_aio_recommend_sleep_for_read_threads = FALSE;
ulint os_n_file_reads = 0;
ulint os_bytes_read_since_printout = 0;
@ -158,7 +158,7 @@ ibool os_has_said_disk_full = FALSE;
/* The mutex protecting the following counts of pending pread and pwrite
operations */
os_mutex_t os_file_count_mutex;
static os_mutex_t os_file_count_mutex;
ulint os_file_n_pending_preads = 0;
ulint os_file_n_pending_pwrites = 0;
@ -3025,7 +3025,7 @@ os_aio_array_reserve_slot(
/* out: pointer to slot */
ulint type, /* in: OS_FILE_READ or OS_FILE_WRITE */
os_aio_array_t* array, /* in: aio array */
void* message1,/* in: message to be passed along with
fil_node_t* message1,/* in: message to be passed along with
the aio operation */
void* message2,/* in: message to be passed along with
the aio operation */
@ -3287,7 +3287,7 @@ os_aio(
ulint offset_high, /* in: most significant 32 bits of
offset */
ulint n, /* in: number of bytes to read or write */
void* message1,/* in: messages for the aio handler (these
fil_node_t* message1,/* in: messages for the aio handler (these
can be used to identify a completed aio
operation); if mode is OS_AIO_SYNC, these
are ignored */
@ -3472,7 +3472,7 @@ os_aio_windows_handle(
ignored */
ulint pos, /* this parameter is used only in sync aio:
wait for the aio slot at this position */
void** message1, /* out: the messages passed with the aio
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
@ -3563,7 +3563,7 @@ os_aio_posix_handle(
/*================*/
/* out: TRUE if the aio operation succeeded */
ulint array_no, /* in: array number 0 - 3 */
void** message1, /* out: the messages passed with the aio
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
@ -3644,7 +3644,7 @@ os_aio_simulated_handle(
i/o thread, segment 1 the log i/o thread,
then follow the non-ibuf read threads, and as
the last are the non-ibuf write threads */
void** message1, /* out: the messages passed with the aio
fil_node_t**message1, /* out: the messages passed with the aio
request; note that also in the case where
the aio operation failed, these output
parameters are valid and can be used to
@ -4182,6 +4182,7 @@ os_aio_refresh_stats(void)
os_last_printout = time(NULL);
}
#ifdef UNIV_DEBUG
/**************************************************************************
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
@ -4241,3 +4242,4 @@ os_aio_all_slots_free(void)
return(FALSE);
}
#endif /* UNIV_DEBUG */

View file

@ -129,7 +129,7 @@ page_cur_try_search_shortcut(
#endif
success = TRUE;
exit_func:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(success);
@ -451,7 +451,7 @@ page_cur_search_with_match(
*iup_matched_bytes = up_matched_bytes;
*ilow_matched_fields = low_matched_fields;
*ilow_matched_bytes = low_matched_bytes;
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -515,8 +515,12 @@ page_cur_insert_rec_write_log(
byte* log_ptr;
byte* log_end;
ulint i;
ulint comp;
ut_a(rec_size < UNIV_PAGE_SIZE);
ut_ad(buf_frame_align(insert_rec) == buf_frame_align(cursor_rec));
ut_ad(!page_rec_is_comp(insert_rec) == !index->table->comp);
comp = page_rec_is_comp(insert_rec);
{
mem_heap_t* heap = NULL;
@ -539,7 +543,7 @@ page_cur_insert_rec_write_log(
ut_ad(rec_size == rec_offs_size(ins_offs));
cur_rec_size = rec_offs_size(cur_offs);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -565,7 +569,7 @@ page_cur_insert_rec_write_log(
ins_ptr++;
cur_ptr++;
} else if ((i < extra_size)
&& (i >= extra_size - (index->table->comp
&& (i >= extra_size - (comp
? REC_N_NEW_EXTRA_BYTES
: REC_N_OLD_EXTRA_BYTES))) {
i = extra_size;
@ -580,7 +584,7 @@ page_cur_insert_rec_write_log(
if (mtr_get_log_mode(mtr) != MTR_LOG_SHORT_INSERTS) {
log_ptr = mlog_open_and_write_index(mtr, insert_rec, index,
index->table->comp
comp
? MLOG_COMP_REC_INSERT : MLOG_REC_INSERT,
2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN);
@ -605,8 +609,8 @@ page_cur_insert_rec_write_log(
log_end = &log_ptr[5 + 1 + 5 + 5 + MLOG_BUF_MARGIN];
}
if ((rec_get_info_and_status_bits(insert_rec, index->table->comp) !=
rec_get_info_and_status_bits(cursor_rec, index->table->comp))
if ((rec_get_info_and_status_bits(insert_rec, comp) !=
rec_get_info_and_status_bits(cursor_rec, comp))
|| (extra_size != cur_extra_size)
|| (rec_size != cur_rec_size)) {
@ -622,8 +626,7 @@ page_cur_insert_rec_write_log(
if (extra_info_yes) {
/* Write the info bits */
mach_write_to_1(log_ptr,
rec_get_info_and_status_bits(insert_rec,
index->table->comp));
rec_get_info_and_status_bits(insert_rec, comp));
log_ptr++;
/* Write the record origin offset */
@ -757,6 +760,8 @@ page_cur_parse_insert_rec(
return(ptr + end_seg_len);
}
ut_ad(!!page_is_comp(page) == index->table->comp);
/* Read from the log the inserted index record end segment which
differs from the cursor record */
@ -771,7 +776,7 @@ page_cur_parse_insert_rec(
if (extra_info_yes == 0) {
info_and_status_bits = rec_get_info_and_status_bits(
cursor_rec, index->table->comp);
cursor_rec, page_is_comp(page));
origin_offset = rec_offs_extra_size(offsets);
mismatch_index = rec_offs_size(offsets) - end_seg_len;
}
@ -807,7 +812,7 @@ page_cur_parse_insert_rec(
ut_memcpy(buf, rec_get_start(cursor_rec, offsets), mismatch_index);
ut_memcpy(buf + mismatch_index, ptr, end_seg_len);
rec_set_info_and_status_bits(buf + origin_offset, index->table->comp,
rec_set_info_and_status_bits(buf + origin_offset, page_is_comp(page),
info_and_status_bits);
page_cur_position(cursor_rec, &cursor);
@ -821,7 +826,7 @@ page_cur_parse_insert_rec(
mem_free(buf);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@ -861,7 +866,7 @@ page_cur_insert_rec_low(
rec_t* owner_rec;
ulint n_owned;
mem_heap_t* heap = NULL;
ibool comp = index->table->comp;
ulint comp;
ut_ad(cursor && mtr);
ut_ad(tuple || rec);
@ -869,8 +874,8 @@ page_cur_insert_rec_low(
ut_ad(rec || dtuple_check_typed(tuple));
page = page_cur_get_page(cursor);
ut_ad(page_is_comp(page) == comp);
comp = page_is_comp(page);
ut_ad(index->table->comp == !!comp);
ut_ad(cursor->rec != page_get_supremum_rec(page));
@ -890,7 +895,7 @@ page_cur_insert_rec_low(
insert_buf = page_mem_alloc(page, rec_size, index, &heap_no);
if (insert_buf == NULL) {
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(NULL);
@ -980,7 +985,7 @@ page_cur_insert_rec_low(
page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,
index, mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(insert_rec);
@ -1000,8 +1005,10 @@ page_copy_rec_list_to_created_page_write_log(
{
byte* log_ptr;
ut_ad(!!page_is_comp(page) == index->table->comp);
log_ptr = mlog_open_and_write_index(mtr, page, index,
index->table->comp
page_is_comp(page)
? MLOG_COMP_LIST_END_COPY_CREATED
: MLOG_LIST_END_COPY_CREATED, 4);
ut_a(log_ptr);
@ -1084,7 +1091,7 @@ page_copy_rec_list_end_to_created_page(
ulint log_mode;
byte* log_ptr;
ulint log_data_len;
ibool comp = page_is_comp(page);
ulint comp = page_is_comp(page);
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
@ -1186,7 +1193,7 @@ page_copy_rec_list_end_to_created_page(
slot_index--;
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@ -1230,8 +1237,10 @@ page_cur_delete_rec_write_log(
{
byte* log_ptr;
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
log_ptr = mlog_open_and_write_index(mtr, rec, index,
index->table->comp
page_rec_is_comp(rec)
? MLOG_COMP_REC_DELETE
: MLOG_REC_DELETE, 2);
@ -1242,7 +1251,7 @@ page_cur_delete_rec_write_log(
}
/* Write the cursor rec offset as a 2-byte ulint */
mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
mlog_close(mtr, log_ptr + 2);
}
@ -1285,7 +1294,7 @@ page_cur_parse_delete_rec(
page_cur_delete_rec(&cursor, index,
rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap), mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -1320,6 +1329,7 @@ page_cur_delete_rec(
page = page_cur_get_page(cursor);
current_rec = cursor->rec;
ut_ad(rec_offs_validate(current_rec, index, offsets));
ut_ad(!!page_is_comp(page) == index->table->comp);
/* The record must not be the supremum or infimum record. */
ut_ad(current_rec != page_get_supremum_rec(page));

View file

@ -72,65 +72,70 @@ page_dir_find_owner_slot(
/* out: the directory slot number */
rec_t* rec) /* in: the physical record */
{
ulint i;
ulint steps = 0;
page_t* page;
page_dir_slot_t* slot;
rec_t* original_rec = rec;
ibool comp;
page_t* page;
register uint16 rec_offs_bytes;
register page_dir_slot_t* slot;
register const page_dir_slot_t* first_slot;
register rec_t* r = rec;
ut_ad(page_rec_check(rec));
page = buf_frame_align(rec);
comp = page_is_comp(page);
first_slot = page_dir_get_nth_slot(page, 0);
slot = page_dir_get_nth_slot(page, page_dir_get_n_slots(page) - 1);
while (rec_get_n_owned(rec, comp) == 0) {
steps++;
rec = page_rec_get_next(rec);
if (page_is_comp(page)) {
while (rec_get_n_owned(r, TRUE) == 0) {
r = page + rec_get_next_offs(r, TRUE);
ut_ad(r >= page + PAGE_NEW_SUPREMUM);
ut_ad(r < page + (UNIV_PAGE_SIZE - PAGE_DIR));
}
} else {
while (rec_get_n_owned(r, FALSE) == 0) {
r = page + rec_get_next_offs(r, FALSE);
ut_ad(r >= page + PAGE_OLD_SUPREMUM);
ut_ad(r < page + (UNIV_PAGE_SIZE - PAGE_DIR));
}
}
page = buf_frame_align(rec);
i = page_dir_get_n_slots(page) - 1;
slot = page_dir_get_nth_slot(page, i);
rec_offs_bytes = mach_encode_2(r - page);
while (page_dir_slot_get_rec(slot) != rec) {
while (UNIV_LIKELY(*(uint16*) slot != rec_offs_bytes)) {
if (i == 0) {
if (UNIV_UNLIKELY(slot == first_slot)) {
fprintf(stderr,
"InnoDB: Probable data corruption on page %lu\n"
"InnoDB: Original record ",
(ulong) buf_frame_get_page_no(page));
if (comp) {
fputs("(compact record)", stderr);
} else {
rec_print_old(stderr, original_rec);
}
fprintf(stderr, "\n"
"InnoDB: on that page. Steps %lu.\n", (ulong) steps);
fputs(
"InnoDB: Cannot find the dir slot for record ",
stderr);
if (comp) {
if (page_is_comp(page)) {
fputs("(compact record)", stderr);
} else {
rec_print_old(stderr, rec);
}
fputs("\n"
"InnoDB: on that page.\n"
"InnoDB: Cannot find the dir slot for record ",
stderr);
if (page_is_comp(page)) {
fputs("(compact record)", stderr);
} else {
rec_print_old(stderr, page
+ mach_decode_2(rec_offs_bytes));
}
fputs("\n"
"InnoDB: on that page!\n", stderr);
buf_page_print(page);
ut_error;
}
ut_error;
}
i--;
slot = page_dir_get_nth_slot(page, i);
slot += PAGE_DIR_SLOT_SIZE;
}
return(i);
return(((ulint) (first_slot - slot)) / PAGE_DIR_SLOT_SIZE);
}
/******************************************************************
@ -252,13 +257,13 @@ page_mem_alloc(
*heap_no = rec_get_heap_no(rec, page_is_comp(page));
block = rec_get_start(rec, offsets);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(block);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -290,7 +295,7 @@ page_create_write_log(
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
mtr_t* mtr, /* in: mini-transaction handle */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
mlog_write_initial_log_record(frame,
comp ? MLOG_COMP_PAGE_CREATE : MLOG_PAGE_CREATE, mtr);
@ -305,7 +310,7 @@ page_parse_create(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr __attribute__((unused)), /* 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 */
{
@ -330,7 +335,7 @@ page_create(
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
mtr_t* mtr, /* in: mini-transaction handle */
ibool comp) /* in: TRUE=compact page format */
ulint comp) /* in: nonzero=compact page format */
{
page_dir_slot_t* slot;
mem_heap_t* heap;
@ -396,9 +401,9 @@ page_create(
dtuple_set_info_bits(tuple, REC_STATUS_SUPREMUM);
field = dtuple_get_nth_field(tuple, 0);
dfield_set_data(field, "supremum", 9 - comp);
dfield_set_data(field, "supremum", comp ? 8 : 9);
dtype_set(dfield_get_type(field),
DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 9 - comp, 0);
DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, comp ? 8 : 9, 0);
supremum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
@ -478,10 +483,11 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
}
ut_a(index->table->comp == page_is_comp(page));
ut_a(index->table->comp == page_is_comp(new_page));
ut_a(!!page_is_comp(new_page) == index->table->comp);
ut_a(page_is_comp(new_page) == page_is_comp(page));
ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
(index->table->comp ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
(page_is_comp(new_page)
? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
page_cur_set_before_first(new_page, &cur2);
@ -489,12 +495,15 @@ page_copy_rec_list_end_no_locks(
sup = page_get_supremum_rec(page);
while (sup != page_cur_get_rec(&cur1)) {
for (;;) {
rec_t* cur1_rec = page_cur_get_rec(&cur1);
if (cur1_rec == sup) {
break;
}
offsets = rec_get_offsets(cur1_rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (!page_cur_rec_insert(&cur2, cur1_rec, index,
offsets, mtr)) {
if (UNIV_UNLIKELY(!page_cur_rec_insert(&cur2, cur1_rec, index,
offsets, mtr))) {
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
@ -514,7 +523,7 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur2);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -608,7 +617,7 @@ page_copy_rec_list_start(
btr_search_move_or_delete_hash_entries(new_page, page, index);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -619,7 +628,6 @@ UNIV_INLINE
void
page_delete_rec_list_write_log(
/*===========================*/
page_t* page, /* in: index page */
rec_t* rec, /* in: record on page */
dict_index_t* index, /* in: record descriptor */
byte type, /* in: operation type:
@ -632,10 +640,10 @@ page_delete_rec_list_write_log(
|| type == MLOG_COMP_LIST_END_DELETE
|| type == MLOG_COMP_LIST_START_DELETE);
log_ptr = mlog_open_and_write_index(mtr, page, index, type, 2);
log_ptr = mlog_open_and_write_index(mtr, rec, index, type, 2);
if (log_ptr) {
/* Write the parameter as a 2-byte ulint */
mach_write_to_2(log_ptr, rec - page);
mach_write_to_2(log_ptr, ut_align_offset(rec, UNIV_PAGE_SIZE));
mlog_close(mtr, log_ptr + 2);
}
}
@ -679,6 +687,8 @@ page_parse_delete_rec_list(
return(ptr);
}
ut_ad(!!page_is_comp(page) == index->table->comp);
if (type == MLOG_LIST_END_DELETE
|| type == MLOG_COMP_LIST_END_DELETE) {
page_delete_rec_list_end(page, page + offset, index,
@ -716,7 +726,7 @@ page_delete_rec_list_end(
ulint count;
ulint n_owned;
rec_t* sup;
ibool comp;
ulint comp;
/* Reset the last insert info in the page header and increment
the modify clock for the frame */
@ -731,12 +741,12 @@ page_delete_rec_list_end(
sup = page_get_supremum_rec(page);
if (rec == page_get_infimum_rec(page)) {
comp = page_is_comp(page);
if (page_rec_is_infimum_low(rec - page)) {
rec = page_rec_get_next(rec);
}
comp = page_is_comp(page);
page_delete_rec_list_write_log(page, rec, index,
page_delete_rec_list_write_log(rec, index,
comp ? MLOG_COMP_LIST_END_DELETE : MLOG_LIST_END_DELETE, mtr);
if (rec == sup) {
@ -772,7 +782,7 @@ page_delete_rec_list_end(
rec2 = page_rec_get_next(rec2);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -841,13 +851,15 @@ page_delete_rec_list_start(
byte type;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
if (index->table->comp) {
ut_ad(!!page_is_comp(page) == index->table->comp);
if (page_is_comp(page)) {
type = MLOG_COMP_LIST_START_DELETE;
} else {
type = MLOG_LIST_START_DELETE;
}
page_delete_rec_list_write_log(page, rec, index, type, mtr);
page_delete_rec_list_write_log(rec, index, type, mtr);
page_cur_set_before_first(page, &cur1);
@ -868,7 +880,7 @@ page_delete_rec_list_start(
page_cur_delete_rec(&cur1, index, offsets, mtr);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@ -1221,7 +1233,7 @@ page_rec_get_n_recs_before(
rec_t* slot_rec;
page_t* page;
ulint i;
ibool comp;
ulint comp;
lint n = 0;
ut_ad(page_rec_check(rec));
@ -1264,9 +1276,9 @@ page_rec_print(
rec_t* rec, /* in: physical record */
const ulint* offsets)/* in: record descriptor */
{
ibool comp = page_is_comp(buf_frame_align(rec));
ulint comp = page_is_comp(buf_frame_align(rec));
ut_a(comp == rec_offs_comp(offsets));
ut_a(!comp == !rec_offs_comp(offsets));
rec_print_new(stderr, rec, offsets);
fprintf(stderr,
" n_owned: %lu; heap_no: %lu; next rec: %lu\n",
@ -1335,7 +1347,7 @@ page_print_list(
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
ut_a(page_is_comp(page) == index->table->comp);
ut_a(!!page_is_comp(page) == index->table->comp);
fprintf(stderr,
"--------------------------------\n"
@ -1381,7 +1393,7 @@ page_print_list(
"--------------------------------\n",
(ulong) (count + 1));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -1447,11 +1459,11 @@ page_rec_validate(
ulint n_owned;
ulint heap_no;
page_t* page;
ibool comp;
ulint comp;
page = buf_frame_align(rec);
comp = page_is_comp(page);
ut_a(comp == rec_offs_comp(offsets));
ut_a(!comp == !rec_offs_comp(offsets));
page_rec_check(rec);
rec_validate(rec, offsets);
@ -1528,7 +1540,7 @@ page_simple_validate(
ulint count;
ulint own_count;
ibool ret = FALSE;
ibool comp = page_is_comp(page);
ulint comp = page_is_comp(page);
/* Check first that the record heap and the directory do not
overlap. */
@ -1725,11 +1737,11 @@ page_validate(
ulint n_slots;
ibool ret = FALSE;
ulint i;
ibool comp = page_is_comp(page);
ulint comp = page_is_comp(page);
ulint* offsets = NULL;
ulint* old_offsets = NULL;
if (comp != index->table->comp) {
if (!!comp != index->table->comp) {
fputs("InnoDB: 'compact format' flag mismatch\n", stderr);
goto func_exit2;
}
@ -1810,8 +1822,7 @@ page_validate(
}
}
if ((rec != page_get_supremum_rec(page))
&& (rec != page_get_infimum_rec(page))) {
if (page_rec_is_user_rec(rec)) {
data_size += rec_offs_size(offsets);
}

View file

@ -320,7 +320,7 @@ cmp_data_data_slow(
|| (cur_type->mtype == DATA_BLOB
&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
&& dtype_get_charset_coll(cur_type->prtype) !=
data_mysql_latin1_swedish_charset_coll)) {
DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
return(cmp_whole_field(cur_type,
data1, (unsigned) len1,
@ -451,6 +451,20 @@ cmp_dtuple_rec_with_match(
ut_ad(cur_field <= dtuple_get_n_fields_cmp(dtuple));
ut_ad(cur_field <= rec_offs_n_fields(offsets));
if (cur_bytes == 0 && cur_field == 0) {
ulint rec_info = rec_get_info_bits(rec,
rec_offs_comp(offsets));
ulint tup_info = dtuple_get_info_bits(dtuple);
if (rec_info & REC_INFO_MIN_REC_FLAG) {
ret = !(tup_info & REC_INFO_MIN_REC_FLAG);
goto order_resolved;
} else if (tup_info & REC_INFO_MIN_REC_FLAG) {
ret = -1;
goto order_resolved;
}
}
/* Match fields in a loop; stop if we run out of fields in dtuple
or find an externally stored field */
@ -469,32 +483,7 @@ cmp_dtuple_rec_with_match(
the predefined minimum record, or the field is externally
stored */
if (cur_bytes == 0) {
if (cur_field == 0) {
if (rec_get_info_bits(rec,
rec_offs_comp(offsets))
& REC_INFO_MIN_REC_FLAG) {
if (dtuple_get_info_bits(dtuple)
& REC_INFO_MIN_REC_FLAG) {
ret = 0;
} else {
ret = 1;
}
goto order_resolved;
}
if (dtuple_get_info_bits(dtuple)
& REC_INFO_MIN_REC_FLAG) {
ret = -1;
goto order_resolved;
}
}
if (UNIV_LIKELY(cur_bytes == 0)) {
if (rec_offs_nth_extern(offsets, cur_field)) {
/* We do not compare to an externally
stored field */
@ -504,24 +493,20 @@ cmp_dtuple_rec_with_match(
goto order_resolved;
}
if (dtuple_f_len == UNIV_SQL_NULL
|| rec_f_len == UNIV_SQL_NULL) {
if (dtuple_f_len == rec_f_len) {
if (dtuple_f_len == UNIV_SQL_NULL) {
if (rec_f_len == UNIV_SQL_NULL) {
goto next_field;
}
if (rec_f_len == UNIV_SQL_NULL) {
/* We define the SQL null to be the
smallest possible value of a field
in the alphabetical order */
ret = 1;
} else {
ret = -1;
}
ret = -1;
goto order_resolved;
} else if (rec_f_len == UNIV_SQL_NULL) {
/* We define the SQL null to be the
smallest possible value of a field
in the alphabetical order */
ret = 1;
goto order_resolved;
}
}
@ -530,7 +515,7 @@ cmp_dtuple_rec_with_match(
|| (cur_type->mtype == DATA_BLOB
&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
&& dtype_get_charset_coll(cur_type->prtype) !=
data_mysql_latin1_swedish_charset_coll)) {
DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
ret = cmp_whole_field(
cur_type,
@ -555,7 +540,7 @@ cmp_dtuple_rec_with_match(
/* Compare then the fields */
for (;;) {
if (rec_f_len <= cur_bytes) {
if (UNIV_UNLIKELY(rec_f_len <= cur_bytes)) {
if (dtuple_f_len <= cur_bytes) {
goto next_field;
@ -572,7 +557,7 @@ cmp_dtuple_rec_with_match(
rec_byte = *rec_b_ptr;
}
if (dtuple_f_len <= cur_bytes) {
if (UNIV_UNLIKELY(dtuple_f_len <= cur_bytes)) {
dtuple_byte = dtype_get_pad_char(cur_type);
if (dtuple_byte == ULINT_UNDEFINED) {
@ -600,14 +585,16 @@ cmp_dtuple_rec_with_match(
rec_byte = cmp_collate(rec_byte);
dtuple_byte = cmp_collate(dtuple_byte);
}
if (dtuple_byte > rec_byte) {
ret = 1;
goto order_resolved;
} else if (dtuple_byte < rec_byte) {
ret = -1;
goto order_resolved;
ret = dtuple_byte - rec_byte;
if (UNIV_UNLIKELY(ret)) {
if (ret < 0) {
ret = -1;
goto order_resolved;
} else {
ret = 1;
goto order_resolved;
}
}
next_byte:
/* Next byte */
@ -740,7 +727,7 @@ cmp_rec_rec_with_match(
ulint cur_bytes; /* number of already matched bytes in current
field */
int ret = 3333; /* return value */
ibool comp;
ulint comp;
ut_ad(rec1 && rec2 && index);
ut_ad(rec_offs_validate(rec1, index, offsets1));
@ -832,7 +819,7 @@ cmp_rec_rec_with_match(
|| (cur_type->mtype == DATA_BLOB
&& 0 == (cur_type->prtype & DATA_BINARY_TYPE)
&& dtype_get_charset_coll(cur_type->prtype) !=
data_mysql_latin1_swedish_charset_coll)) {
DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
ret = cmp_whole_field(cur_type,
rec1_b_ptr, (unsigned) rec1_f_len,
@ -983,12 +970,8 @@ cmp_debug_dtuple_rec_with_match(
if (rec_get_info_bits(rec, rec_offs_comp(offsets))
& REC_INFO_MIN_REC_FLAG) {
if (dtuple_get_info_bits(dtuple)
& REC_INFO_MIN_REC_FLAG) {
ret = 0;
} else {
ret = 1;
}
ret = !(dtuple_get_info_bits(dtuple)
& REC_INFO_MIN_REC_FLAG);
goto order_resolved;
}

View file

@ -159,22 +159,20 @@ rec_init_offsets(
ulint* offsets)/* in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint n_fields = rec_offs_n_fields(offsets);
ulint i = 0;
ulint offs;
rec_offs_make_valid(rec, index, offsets);
if (index->table->comp) {
if (UNIV_LIKELY(index->table->comp)) {
const byte* nulls;
const byte* lens;
dict_field_t* field;
dtype_t* type;
ulint null_mask;
ulint status = rec_get_status(rec);
ulint n_node_ptr_field = ULINT_UNDEFINED;
switch (status) {
switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
/* the field is 8 bytes long */
@ -196,56 +194,69 @@ rec_init_offsets(
null_mask = 1;
/* read the lengths of fields 0..n */
for (; i < n_fields; i++) {
ibool is_null = FALSE, is_external = FALSE;
do {
ulint len;
if (i == n_node_ptr_field) {
len = 4;
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
len = offs += 4;
goto resolved;
}
field = dict_index_get_nth_field(index, i);
type = dict_col_get_type(dict_field_get_col(field));
if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
if (!(dtype_get_prtype(dict_col_get_type(
dict_field_get_col(field)))
& DATA_NOT_NULL)) {
/* nullable field => read the null flag */
is_null = (*nulls & null_mask) != 0;
null_mask <<= 1;
if (null_mask == 0x100) {
if (UNIV_UNLIKELY(!(byte) null_mask)) {
nulls--;
null_mask = 1;
}
if (*nulls & null_mask) {
null_mask <<= 1;
/* No length is stored for NULL fields.
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
len = offs | REC_OFFS_SQL_NULL;
goto resolved;
}
null_mask <<= 1;
}
if (is_null) {
/* No length is stored for NULL fields. */
len = 0;
} else if (!field->fixed_len) {
if (UNIV_UNLIKELY(!field->fixed_len)) {
/* Variable-length field: read the length */
dtype_t* type = dict_col_get_type(
dict_field_get_col(field));
len = *lens--;
if (dtype_get_len(type) > 255
|| dtype_get_mtype(type) == DATA_BLOB) {
if (UNIV_UNLIKELY(dtype_get_len(type) > 255)
|| UNIV_UNLIKELY(dtype_get_mtype(type)
== DATA_BLOB)) {
if (len & 0x80) {
/* 1exxxxxxx xxxxxxxx */
is_external = !!(len & 0x40);
len &= 0x3f;
len <<= 8;
len |= *lens--;
offs += len & 0x3fff;
if (UNIV_UNLIKELY(len
& 0x4000)) {
len = offs
| REC_OFFS_EXTERNAL;
} else {
len = offs;
}
goto resolved;
}
}
len = offs += len;
} else {
len = field->fixed_len;
len = offs += field->fixed_len;
}
resolved:
offs += len;
len = offs;
if (is_external) {
len |= REC_OFFS_EXTERNAL;
}
if (is_null) {
len |= REC_OFFS_SQL_NULL;
}
rec_offs_base(offsets)[i + 1] = len;
}
} while (++i < rec_offs_n_fields(offsets));
*rec_offs_base(offsets) =
(rec - (lens + 1)) | REC_OFFS_COMPACT;
@ -253,22 +264,22 @@ rec_init_offsets(
/* Old-style record: determine extra size and end offsets */
offs = REC_N_OLD_EXTRA_BYTES;
if (rec_get_1byte_offs_flag(rec)) {
offs += n_fields;
offs += rec_offs_n_fields(offsets);
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
for (; i < n_fields; i++) {
do {
offs = rec_1_get_field_end_info(rec, i);
if (offs & REC_1BYTE_SQL_NULL_MASK) {
offs &= ~REC_1BYTE_SQL_NULL_MASK;
offs |= REC_OFFS_SQL_NULL;
}
rec_offs_base(offsets)[1 + i] = offs;
}
} while (++i < rec_offs_n_fields(offsets));
} else {
offs += 2 * n_fields;
offs += 2 * rec_offs_n_fields(offsets);
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
for (; i < n_fields; i++) {
do {
offs = rec_2_get_field_end_info(rec, i);
if (offs & REC_2BYTE_SQL_NULL_MASK) {
offs &= ~REC_2BYTE_SQL_NULL_MASK;
@ -279,7 +290,7 @@ rec_init_offsets(
offs |= REC_OFFS_EXTERNAL;
}
rec_offs_base(offsets)[1 + i] = offs;
}
} while (++i < rec_offs_n_fields(offsets));
}
}
}
@ -310,8 +321,9 @@ rec_get_offsets_func(
ut_ad(index);
ut_ad(heap);
if (index->table->comp) {
switch (rec_get_status(rec)) {
if (UNIV_LIKELY(index->table->comp)) {
switch (UNIV_EXPECT(rec_get_status(rec),
REC_STATUS_ORDINARY)) {
case REC_STATUS_ORDINARY:
n = dict_index_get_n_fields(index);
break;
@ -331,13 +343,14 @@ rec_get_offsets_func(
n = rec_get_n_fields_old(rec);
}
if (n_fields < n) {
if (UNIV_UNLIKELY(n_fields < n)) {
n = n_fields;
}
size = n + (1 + REC_OFFS_HEADER_SIZE);
if (!offsets || rec_offs_get_n_alloc(offsets) < size) {
if (UNIV_UNLIKELY(!offsets) ||
UNIV_UNLIKELY(rec_offs_get_n_alloc(offsets) < size)) {
if (!*heap) {
*heap = mem_heap_create_func(size * sizeof(ulint),
NULL, MEM_HEAP_DYNAMIC, file, line);
@ -652,9 +665,17 @@ rec_set_field_extern_bits(
to log about the change */
{
ulint i;
for (i = 0; i < n_fields; i++) {
rec_set_nth_field_extern_bit(rec, index, vec[i], TRUE, mtr);
if (UNIV_LIKELY(index->table->comp)) {
for (i = 0; i < n_fields; i++) {
rec_set_nth_field_extern_bit_new(rec, index, vec[i],
TRUE, mtr);
}
} else {
for (i = 0; i < n_fields; i++) {
rec_set_nth_field_extern_bit_old(rec, vec[i],
TRUE, mtr);
}
}
}
@ -949,7 +970,7 @@ rec_convert_dtuple_to_rec(
ut_ad(dtuple_validate(dtuple));
ut_ad(dtuple_check_typed(dtuple));
if (index->table->comp) {
if (UNIV_LIKELY(index->table->comp)) {
rec = rec_convert_dtuple_to_rec_new(buf, index, dtuple);
} else {
rec = rec_convert_dtuple_to_rec_old(buf, dtuple);
@ -965,7 +986,7 @@ rec_convert_dtuple_to_rec(
offsets = rec_get_offsets(rec, index,
offsets_, ULINT_UNDEFINED, &heap);
ut_ad(rec_validate(rec, offsets));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -1078,17 +1099,19 @@ rec_copy_prefix_to_buf(
for the copied prefix, or NULL */
ulint* buf_size) /* in/out: buffer size */
{
byte* nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
byte* lens = nulls - (index->n_nullable + 7) / 8;
byte* nulls;
byte* lens;
dict_field_t* field;
dtype_t* type;
ulint i;
ulint prefix_len = 0;
ulint prefix_len;
ibool is_null;
ulint null_mask = 1;
ulint null_mask;
ulint status;
if (!index->table->comp) {
UNIV_PREFETCH_RW(*buf);
if (UNIV_UNLIKELY(!index->table->comp)) {
ut_ad(rec_validate_old(rec));
return(rec_copy_prefix_to_buf_old(rec, n_fields,
rec_get_field_start_offs(rec, n_fields),
@ -1109,10 +1132,16 @@ rec_copy_prefix_to_buf(
case REC_STATUS_SUPREMUM:
/* infimum or supremum record: no sense to copy anything */
default:
ut_a(0);
ut_error;
return(NULL);
}
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
lens = nulls - (index->n_nullable + 7) / 8;
UNIV_PREFETCH_R(lens);
prefix_len = 0;
null_mask = 1;
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
field = dict_index_get_nth_field(index, i);
@ -1122,8 +1151,11 @@ rec_copy_prefix_to_buf(
/* nullable field => read the null flag */
is_null = !!(*nulls & null_mask);
null_mask <<= 1;
if (null_mask == 0x100)
nulls--, null_mask = 1;
if (null_mask == 0x100) {
--nulls;
UNIV_PREFETCH_R(nulls);
null_mask = 1;
}
}
if (is_null) {
@ -1138,12 +1170,15 @@ rec_copy_prefix_to_buf(
len &= 0x3f;
len <<= 8;
len |= *lens--;
UNIV_PREFETCH_R(lens);
}
}
prefix_len += len;
}
}
UNIV_PREFETCH_R(rec + prefix_len);
prefix_len += rec - (lens + 1);
if ((*buf == NULL) || (*buf_size < prefix_len)) {
@ -1412,7 +1447,7 @@ rec_print(
rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}

View file

@ -478,7 +478,7 @@ row_ins_cascade_calc_update_vec(
if (parent_ufield->field_no == parent_field_no) {
ulint fixed_size;
ulint min_size;
/* A field in the parent index record is
updated. Let us make the update vector
@ -508,10 +508,13 @@ row_ins_cascade_calc_update_vec(
column, do not allow the update */
if (ufield->new_val.len != UNIV_SQL_NULL
&& ufield->new_val.len
> dtype_get_len(type)) {
&& dtype_get_at_most_n_mbchars(
type, dtype_get_len(type),
ufield->new_val.len,
ufield->new_val.data)
< ufield->new_val.len) {
return(ULINT_UNDEFINED);
return(ULINT_UNDEFINED);
}
/* If the parent column type has a different
@ -519,29 +522,46 @@ row_ins_cascade_calc_update_vec(
need to pad with spaces the new value of the
child column */
fixed_size = dtype_get_fixed_size(type);
min_size = dtype_get_min_size(type);
/* TODO: pad in UCS-2 with 0x0020.
TODO: How does the special truncation of
UTF-8 CHAR cols affect this? */
if (fixed_size
if (min_size
&& ufield->new_val.len != UNIV_SQL_NULL
&& ufield->new_val.len < fixed_size) {
&& ufield->new_val.len < min_size) {
char* pad_start;
const char* pad_end;
ufield->new_val.data =
mem_heap_alloc(heap,
fixed_size);
ufield->new_val.len = fixed_size;
ut_a(dtype_get_pad_char(type)
!= ULINT_UNDEFINED);
memset(ufield->new_val.data,
(byte)dtype_get_pad_char(type),
fixed_size);
min_size);
pad_start = ufield->new_val.data
+ ufield->new_val.len;
pad_end = ufield->new_val.data
+ min_size;
ufield->new_val.len = min_size;
ut_memcpy(ufield->new_val.data,
parent_ufield->new_val.data,
parent_ufield->new_val.len);
switch (UNIV_EXPECT(
dtype_get_mbminlen(type), 1)) {
default:
ut_error;
case 1:
/* space=0x20 */
memset(pad_start, 0x20,
pad_end - pad_start);
break;
case 2:
/* space=0x0020 */
ut_a(!(ufield->new_val.len
% 2));
ut_a(!(min_size % 2));
do {
*pad_start++ = 0x00;
*pad_start++ = 0x20;
} while (pad_start < pad_end);
break;
}
}
ufield->extern_storage = FALSE;
@ -1255,9 +1275,11 @@ run_again:
/* Scan index records and check if there is a matching record */
for (;;) {
page_t* page;
rec = btr_pcur_get_rec(&pcur);
page = buf_frame_align(rec);
if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
if (rec == page_get_infimum_rec(page)) {
goto next_rec;
}
@ -1265,7 +1287,7 @@ run_again:
offsets = rec_get_offsets(rec, check_index,
offsets, ULINT_UNDEFINED, &heap);
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
if (rec == page_get_supremum_rec(page)) {
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, rec,
check_index, offsets, thr);
@ -1392,7 +1414,7 @@ do_possible_lock_wait:
}
exit_func:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@ -1529,12 +1551,7 @@ row_ins_dupl_error_with_rec(
}
}
if (!rec_get_deleted_flag(rec, index->table->comp)) {
return(TRUE);
}
return(FALSE);
return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
}
/*******************************************************************
@ -1629,7 +1646,7 @@ row_ins_scan_sec_index_for_duplicate(
break;
}
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
if (page_rec_is_supremum(rec)) {
goto next_rec;
}
@ -1660,7 +1677,7 @@ next_rec:
}
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
mtr_commit(&mtr);
@ -1697,7 +1714,6 @@ row_ins_duplicate_error_in_clust(
#ifndef UNIV_HOTBACKUP
ulint err;
rec_t* rec;
page_t* page;
ulint n_unique;
trx_t* trx = thr_get_trx(thr);
mem_heap_t*heap = NULL;
@ -1728,9 +1744,8 @@ row_ins_duplicate_error_in_clust(
if (cursor->low_match >= n_unique) {
rec = btr_cur_get_rec(cursor);
page = buf_frame_align(rec);
if (rec != page_get_infimum_rec(page)) {
if (!page_rec_is_infimum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
@ -1772,9 +1787,8 @@ row_ins_duplicate_error_in_clust(
if (cursor->up_match >= n_unique) {
rec = page_rec_get_next(btr_cur_get_rec(cursor));
page = buf_frame_align(rec);
if (rec != page_get_supremum_rec(page)) {
if (!page_rec_is_supremum(rec)) {
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
@ -1842,7 +1856,6 @@ row_ins_must_modify(
{
ulint enough_match;
rec_t* rec;
page_t* page;
/* NOTE: (compare to the note in row_ins_duplicate_error) Because node
pointers on upper levels of the B-tree may match more to entry than
@ -1856,9 +1869,8 @@ row_ins_must_modify(
if (cursor->low_match >= enough_match) {
rec = btr_cur_get_rec(cursor);
page = buf_frame_align(rec);
if (rec != page_get_infimum_rec(page)) {
if (!page_rec_is_infimum(rec)) {
return(ROW_INS_PREV);
}
@ -1897,7 +1909,6 @@ row_ins_index_entry_low(
ulint modify = 0; /* remove warning */
rec_t* insert_rec;
rec_t* rec;
rec_t* first_rec;
ulint err;
ulint n_unique;
big_rec_t* big_rec = NULL;
@ -1932,16 +1943,21 @@ row_ins_index_entry_low(
err = DB_SUCCESS;
goto function_exit;
}
first_rec = page_rec_get_next(page_get_infimum_rec(
buf_frame_align(btr_cur_get_rec(&cursor))));
if (!page_rec_is_supremum(first_rec)) {
ut_a(rec_get_n_fields(first_rec, index)
== dtuple_get_n_fields(entry));
}
#ifdef UNIV_DEBUG
{
page_t* page = btr_cur_get_page(&cursor);
rec_t* first_rec = page_rec_get_next(
page_get_infimum_rec(page));
if (UNIV_LIKELY(first_rec != page_get_supremum_rec(page))) {
ut_a(rec_get_n_fields(first_rec, index)
== dtuple_get_n_fields(entry));
}
}
#endif
n_unique = dict_index_get_n_unique(index);
if (index->type & DICT_UNIQUE && (cursor.up_match >= n_unique
@ -2048,7 +2064,7 @@ function_exit:
mtr_commit(&mtr);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);

View file

@ -265,7 +265,7 @@ row_mysql_store_col_in_innobase_format(
necessarily the length of the actual
payload data; if the column is a true
VARCHAR then this is irrelevant */
ibool comp) /* in: TRUE = compact format */
ulint comp) /* in: nonzero=compact format */
{
byte* ptr = mysql_data;
dtype_t* dtype;
@ -970,25 +970,6 @@ run_again:
return((int) err);
}
/*************************************************************************
Unlocks all table locks explicitly requested by trx (with LOCK TABLES,
lock type LOCK_TABLE_EXP). */
void
row_unlock_tables_for_mysql(
/*========================*/
trx_t* trx) /* in: transaction */
{
if (!trx->n_lock_table_exp) {
return;
}
mutex_enter(&kernel_mutex);
lock_release_tables_off_kernel(trx);
mutex_exit(&kernel_mutex);
}
/*************************************************************************
Sets a table lock on the table mentioned in prebuilt. */
@ -1000,9 +981,10 @@ row_lock_table_for_mysql(
table handle */
dict_table_t* table, /* in: table to lock, or NULL
if prebuilt->table should be
locked or a
locked as
prebuilt->select_lock_type */
ulint mode) /* in: lock mode of table */
ulint mode) /* in: lock mode of table
(ignored if table==NULL) */
{
trx_t* trx = prebuilt->trx;
que_thr_t* thr;
@ -1038,14 +1020,8 @@ run_again:
if (table) {
err = lock_table(0, table, mode, thr);
} else {
if (mode == LOCK_TABLE_TRANSACTIONAL) {
err = lock_table(LOCK_TABLE_TRANSACTIONAL,
prebuilt->table,
prebuilt->select_lock_type, thr);
} else {
err = lock_table(LOCK_TABLE_EXP, prebuilt->table,
prebuilt->select_lock_type, thr);
}
err = lock_table(0, prebuilt->table,
prebuilt->select_lock_type, thr);
}
trx->error_state = err;
@ -3858,7 +3834,7 @@ funct_exit:
que_graph_free(graph);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@ -3893,6 +3869,7 @@ row_scan_and_check_index(
int cmp;
ibool contains_null;
ulint i;
ulint cnt;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
@ -3915,11 +3892,19 @@ row_scan_and_check_index(
dtuple_set_n_fields(prebuilt->search_tuple, 0);
prebuilt->select_lock_type = LOCK_NONE;
cnt = 1000;
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
loop:
/* Check thd->killed every 1,000 scanned rows */
if (--cnt == 0) {
if (trx_is_interrupted(prebuilt->trx)) {
goto func_exit;
}
cnt = 1000;
}
if (ret != DB_SUCCESS) {
func_exit:
mem_free(buf);
mem_heap_free(heap);
@ -4046,7 +4031,7 @@ row_check_table_for_mysql(
ut_print_name(stderr, index->name);
putc('\n', stderr); */
if (!btr_validate_tree(index->tree)) {
if (!btr_validate_tree(index->tree, prebuilt->trx)) {
ret = DB_ERROR;
} else {
if (!row_scan_and_check_index(prebuilt,
@ -4054,6 +4039,10 @@ row_check_table_for_mysql(
ret = DB_ERROR;
}
if (trx_is_interrupted(prebuilt->trx)) {
break;
}
/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
index->name); */

View file

@ -126,7 +126,7 @@ row_purge_remove_clust_if_poss_low(
if (0 != ut_dulint_cmp(node->roll_ptr,
row_get_rec_roll_ptr(rec, index, rec_get_offsets(
rec, index, offsets_, ULINT_UNDEFINED, &heap)))) {
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
/* Someone else has modified the record later: do not remove */
@ -135,7 +135,7 @@ row_purge_remove_clust_if_poss_low(
return(TRUE);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}

View file

@ -535,7 +535,7 @@ row_build_row_ref_in_tuple(
}
ut_ad(dtuple_check_typed(ref));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -616,7 +616,6 @@ row_search_on_row_ref(
ulint low_match;
rec_t* rec;
dict_index_t* index;
page_t* page;
ut_ad(dtuple_check_typed(ref));
@ -629,9 +628,8 @@ row_search_on_row_ref(
low_match = btr_pcur_get_low_match(pcur);
rec = btr_pcur_get_rec(pcur);
page = buf_frame_align(rec);
if (rec == page_get_infimum_rec(page)) {
if (page_rec_is_infimum(rec)) {
return(FALSE);
}
@ -702,7 +700,6 @@ row_search_index_entry(
{
ulint n_fields;
ulint low_match;
page_t* page;
rec_t* rec;
ut_ad(dtuple_check_typed(entry));
@ -711,11 +708,10 @@ row_search_index_entry(
low_match = btr_pcur_get_low_match(pcur);
rec = btr_pcur_get_rec(pcur);
page = buf_frame_align(rec);
n_fields = dtuple_get_n_fields(entry);
if (rec == page_get_infimum_rec(page)) {
if (page_rec_is_infimum(rec)) {
return(FALSE);
}

View file

@ -125,7 +125,7 @@ row_sel_sec_rec_is_for_clust_rec(
}
func_exit:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(is_equal);
@ -630,6 +630,8 @@ row_sel_get_clust_rec(
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
*out_rec = NULL;
offsets = rec_get_offsets(rec,
btr_pcur_get_btr_cur(&plan->pcur)->index,
offsets, ULINT_UNDEFINED, &heap);
@ -663,8 +665,6 @@ row_sel_get_clust_rec(
clustered index record did not exist in the read view of
trx. */
clust_rec = NULL;
goto func_exit;
}
@ -733,7 +733,6 @@ row_sel_get_clust_rec(
if ((old_vers || rec_get_deleted_flag(rec, plan->table->comp))
&& !row_sel_sec_rec_is_for_clust_rec(rec, plan->index,
clust_rec, index)) {
clust_rec = NULL;
goto func_exit;
}
}
@ -742,11 +741,11 @@ row_sel_get_clust_rec(
row_sel_fetch_columns(index, clust_rec, offsets,
UT_LIST_GET_FIRST(plan->columns));
func_exit:
*out_rec = clust_rec;
func_exit:
err = DB_SUCCESS;
err_exit:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@ -1066,7 +1065,7 @@ row_sel_try_search_shortcut(
plan->n_rows_fetched++;
func_exit:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(SEL_FOUND);
@ -1261,7 +1260,7 @@ rec_loop:
/* PHASE 1: Set a lock if specified */
if (!node->asc && cursor_just_opened
&& (rec != page_get_supremum_rec(buf_frame_align(rec)))) {
&& !page_rec_is_supremum(rec)) {
/* When we open a cursor for a descending search, we must set
a next-key lock on the successor record: otherwise it would
@ -1299,7 +1298,7 @@ rec_loop:
}
}
if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
if (page_rec_is_infimum(rec)) {
/* The infimum record on a page cannot be in the result set,
and neither can a record lock be placed on it: we skip such
@ -1337,7 +1336,7 @@ rec_loop:
}
}
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
if (page_rec_is_supremum(rec)) {
/* A page supremum record cannot be in the result set: skip
it now when we have placed a possible lock on it */
@ -1780,7 +1779,7 @@ lock_wait_or_error:
ut_ad(sync_thread_levels_empty_gen(TRUE));
func_exit:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@ -2416,14 +2415,12 @@ row_sel_store_mysql_rec(
mem_heap_t* extern_field_heap = NULL;
byte* data;
ulint len;
byte* blob_buf;
int pad_char;
ulint i;
ut_ad(prebuilt->mysql_template);
ut_ad(rec_offs_validate(rec, NULL, offsets));
if (prebuilt->blob_heap != NULL) {
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
mem_heap_free(prebuilt->blob_heap);
prebuilt->blob_heap = NULL;
}
@ -2435,7 +2432,8 @@ row_sel_store_mysql_rec(
data = rec_get_nth_field(rec, offsets,
templ->rec_field_no, &len);
if (rec_offs_nth_extern(offsets, templ->rec_field_no)) {
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
templ->rec_field_no))) {
/* Copy an externally stored field to the temporary
heap */
@ -2456,7 +2454,7 @@ row_sel_store_mysql_rec(
}
if (len != UNIV_SQL_NULL) {
if (templ->type == DATA_BLOB) {
if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
ut_a(prebuilt->templ_contains_blob);
@ -2465,8 +2463,9 @@ row_sel_store_mysql_rec(
of 1000000 bytes. Since the test takes some
CPU time, we do not use it for small BLOBs. */
if (len > 2000000
&& !ut_test_malloc(len + 1000000)) {
if (UNIV_UNLIKELY(len > 2000000)
&& UNIV_UNLIKELY(!ut_test_malloc(
len + 1000000))) {
ut_print_timestamp(stderr);
fprintf(stderr,
@ -2492,11 +2491,9 @@ row_sel_store_mysql_rec(
mem_heap_create(len);
}
blob_buf = mem_heap_alloc(prebuilt->blob_heap,
len);
ut_memcpy(blob_buf, data, len);
data = blob_buf;
data = memcpy(mem_heap_alloc(
prebuilt->blob_heap, len),
data, len);
}
row_sel_field_store_in_mysql_format(
@ -2521,41 +2518,45 @@ row_sel_store_mysql_rec(
account caused seg faults with NULL BLOB fields, and
bug number 154 in the MySQL bug database: GROUP BY
and DISTINCT could treat NULL values inequal. */
int pad_char;
mysql_rec[templ->mysql_null_byte_offset] |=
(byte) (templ->mysql_null_bit_mask);
if (templ->type == DATA_VARCHAR
|| templ->type == DATA_CHAR
|| templ->type == DATA_BINARY
|| templ->type == DATA_FIXBINARY
|| templ->type == DATA_MYSQL
|| templ->type == DATA_VARMYSQL) {
switch (templ->type) {
case DATA_VARCHAR:
case DATA_CHAR:
case DATA_BINARY:
case DATA_FIXBINARY:
case DATA_MYSQL:
case DATA_VARMYSQL:
/* MySQL pads all non-BLOB and non-TEXT
string types with space ' ' */
pad_char = ' ';
} else {
pad_char = '\0';
if (UNIV_UNLIKELY(templ->mbminlen == 2)) {
/* Treat UCS2 as a special case. */
data = mysql_rec
+ templ->mysql_col_offset;
len = templ->mysql_col_len;
/* There are two UCS2 bytes per char,
so the length has to be even. */
ut_a(!(len & 1));
/* Pad with 0x0020. */
while (len) {
*data++ = 0x00;
*data++ = 0x20;
len -= 2;
}
continue;
}
pad_char = 0x20;
break;
default:
pad_char = 0x00;
break;
}
/* Handle UCS2 strings differently. */
if (pad_char != '\0' && templ->mbminlen == 2) {
/* There are two bytes per char, so the length
has to be an even number. */
ut_a(!(templ->mysql_col_len & 1));
data = mysql_rec + templ->mysql_col_offset;
len = templ->mysql_col_len;
/* Pad with 0x0020. */
while (len >= 2) {
*data++ = 0x00;
*data++ = 0x20;
len -= 2;
}
} else {
ut_ad(!pad_char || templ->mbminlen == 1);
memset(mysql_rec + templ->mysql_col_offset,
ut_ad(!pad_char || templ->mbminlen == 1);
memset(mysql_rec + templ->mysql_col_offset,
pad_char, templ->mysql_col_len);
}
}
}
@ -2849,8 +2850,9 @@ row_sel_pop_cached_row_for_mysql(
mysql_row_templ_t* templ;
byte* cached_rec;
ut_ad(prebuilt->n_fetch_cached > 0);
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
if (prebuilt->keep_other_fields_on_keyread)
if (UNIV_UNLIKELY(prebuilt->keep_other_fields_on_keyread))
{
/* Copy cache record field by field, don't touch fields that
are not covered by current key */
@ -2877,7 +2879,7 @@ row_sel_pop_cached_row_for_mysql(
else
{
ut_memcpy(buf, prebuilt->fetch_cache[prebuilt->fetch_cache_first],
prebuilt->mysql_row_len);
prebuilt->mysql_prefix_len);
}
prebuilt->n_fetch_cached--;
prebuilt->fetch_cache_first++;
@ -2925,9 +2927,9 @@ row_sel_push_cache_row_for_mysql(
ut_ad(prebuilt->fetch_cache_first == 0);
if (!row_sel_store_mysql_rec(
if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
prebuilt->fetch_cache[prebuilt->n_fetch_cached],
prebuilt, rec, offsets)) {
prebuilt, rec, offsets))) {
ut_error;
}
@ -3048,11 +3050,7 @@ row_search_for_mysql(
rec_t* index_rec;
rec_t* clust_rec;
rec_t* old_vers;
ulint err = DB_SUCCESS;
ibool moved;
ibool cons_read_requires_clust_rec;
ibool was_lock_wait;
ulint shortcut;
ulint err = DB_SUCCESS;
ibool unique_search = FALSE;
ibool unique_search_from_clust_index = FALSE;
ibool mtr_has_extra_clust_latch = FALSE;
@ -3062,9 +3060,9 @@ row_search_for_mysql(
locking SELECT, and the isolation
level is <= TRX_ISO_READ_COMMITTED,
then this is set to FALSE */
ibool success;
ibool comp;
#ifdef UNIV_SEARCH_DEBUG
ulint cnt = 0;
#endif /* UNIV_SEARCH_DEBUG */
ulint next_offs;
mtr_t mtr;
mem_heap_t* heap = NULL;
@ -3075,7 +3073,7 @@ row_search_for_mysql(
ut_ad(index && pcur && search_tuple);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
if (prebuilt->table->ibd_file_missing) {
if (UNIV_UNLIKELY(prebuilt->table->ibd_file_missing)) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Error:\n"
"InnoDB: MySQL is trying to use a table handle but the .ibd file for\n"
@ -3089,7 +3087,7 @@ row_search_for_mysql(
return(DB_ERROR);
}
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
fprintf(stderr,
"InnoDB: Error: trying to free a corrupt\n"
"InnoDB: table handle. Magic n %lu, table name ",
@ -3103,7 +3101,7 @@ row_search_for_mysql(
}
if (trx->n_mysql_tables_in_use == 0
&& prebuilt->select_lock_type == LOCK_NONE) {
&& UNIV_UNLIKELY(prebuilt->select_lock_type == LOCK_NONE)) {
/* Note that if MySQL uses an InnoDB temp table that it
created inside LOCK TABLES, then n_mysql_tables_in_use can
be zero; in that case select_lock_type is set to LOCK_X in
@ -3126,8 +3124,8 @@ row_search_for_mysql(
/* PHASE 0: Release a possible s-latch we are holding on the
adaptive hash index latch if there is someone waiting behind */
if (trx->has_search_latch
&& btr_search_latch.writer != RW_LOCK_NOT_LOCKED) {
if (UNIV_UNLIKELY(btr_search_latch.writer != RW_LOCK_NOT_LOCKED)
&& trx->has_search_latch) {
/* There is an x-latch request on the adaptive hash index:
release the s-latch to reduce starvation and wait for
@ -3143,7 +3141,7 @@ row_search_for_mysql(
/*-------------------------------------------------------------*/
/* PHASE 1: Try to pop the row from the prefetch cache */
if (direction == 0) {
if (UNIV_UNLIKELY(direction == 0)) {
trx->op_info = "starting index read";
prebuilt->n_rows_fetched = 0;
@ -3161,8 +3159,8 @@ row_search_for_mysql(
prebuilt->fetch_direction = direction;
}
if (direction != prebuilt->fetch_direction) {
if (prebuilt->n_fetch_cached > 0) {
if (UNIV_UNLIKELY(direction != prebuilt->fetch_direction)) {
if (UNIV_UNLIKELY(prebuilt->n_fetch_cached > 0)) {
ut_error;
/* TODO: scrollable cursor: restore cursor to
the place of the latest returned row,
@ -3174,7 +3172,7 @@ row_search_for_mysql(
prebuilt->n_fetch_cached = 0;
prebuilt->fetch_cache_first = 0;
} else if (prebuilt->n_fetch_cached > 0) {
} else if (UNIV_LIKELY(prebuilt->n_fetch_cached > 0)) {
row_sel_pop_cached_row_for_mysql(buf, prebuilt);
prebuilt->n_rows_fetched++;
@ -3234,7 +3232,8 @@ row_search_for_mysql(
1 column. Return immediately if this is not a HANDLER
command. */
if (direction != 0 && !prebuilt->used_in_HANDLER) {
if (UNIV_UNLIKELY(direction != 0 &&
!prebuilt->used_in_HANDLER)) {
err = DB_RECORD_NOT_FOUND;
goto func_exit;
@ -3252,9 +3251,9 @@ row_search_for_mysql(
cannot use the adaptive hash index in a search in the case the row
may be long and there may be externally stored fields */
if (unique_search
if (UNIV_UNLIKELY(direction == 0)
&& unique_search
&& index->type & DICT_CLUSTERED
&& direction == 0
&& !prebuilt->templ_contains_blob
&& !prebuilt->used_in_HANDLER
&& (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) {
@ -3286,9 +3285,9 @@ row_search_for_mysql(
trx->has_search_latch = TRUE;
}
#endif
shortcut = row_sel_try_search_shortcut_for_mysql(&rec,
prebuilt, &offsets, &heap, &mtr);
if (shortcut == SEL_FOUND) {
switch (row_sel_try_search_shortcut_for_mysql(&rec,
prebuilt, &offsets, &heap, &mtr)) {
case SEL_FOUND:
#ifdef UNIV_SEARCH_DEBUG
ut_a(0 == cmp_dtuple_rec(search_tuple,
rec, offsets));
@ -3322,9 +3321,8 @@ row_search_for_mysql(
position */
err = DB_SUCCESS;
goto func_exit;
} else if (shortcut == SEL_EXHAUSTED) {
case SEL_EXHAUSTED:
mtr_commit(&mtr);
/* ut_print_name(stderr, index->name);
@ -3367,6 +3365,7 @@ shortcut_fails_too_big_rec:
/* Scan the MySQL query string; check if SELECT is the first
word there */
ibool success;
dict_accept(*trx->mysql_query_str, "SELECT", &success);
@ -3382,7 +3381,7 @@ shortcut_fails_too_big_rec:
naturally moves upward (in fetch next) in alphabetical order,
otherwise downward */
if (direction == 0) {
if (UNIV_UNLIKELY(direction == 0)) {
if (mode == PAGE_CUR_GE || mode == PAGE_CUR_G) {
moves_up = TRUE;
}
@ -3396,10 +3395,9 @@ shortcut_fails_too_big_rec:
clust_index = dict_table_get_first_index(index->table);
if (direction != 0) {
moved = sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
moves_up, &mtr);
if (!moved) {
if (UNIV_LIKELY(direction != 0)) {
if (!sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
moves_up, &mtr)) {
goto next_rec;
}
@ -3440,11 +3438,13 @@ shortcut_fails_too_big_rec:
trx_assign_read_view(trx);
prebuilt->sql_stat_start = FALSE;
} else {
ulint lock_mode;
if (prebuilt->select_lock_type == LOCK_S) {
err = lock_table(0, index->table, LOCK_IS, thr);
lock_mode = LOCK_IS;
} else {
err = lock_table(0, index->table, LOCK_IX, thr);
lock_mode = LOCK_IX;
}
err = lock_table(0, index->table, lock_mode, thr);
if (err != DB_SUCCESS) {
@ -3458,8 +3458,8 @@ rec_loop:
/* PHASE 4: Look for matching records in a loop */
rec = btr_pcur_get_rec(pcur);
comp = index->table->comp;
ut_ad(comp == page_is_comp(buf_frame_align(rec)));
ut_ad(!!page_rec_is_comp(rec) == index->table->comp);
#ifdef UNIV_SEARCH_DEBUG
/*
fputs("Using ", stderr);
dict_index_name_print(stderr, index);
@ -3467,7 +3467,9 @@ rec_loop:
buf_frame_get_page_no(buf_frame_align(rec)));
rec_print(rec);
*/
if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
#endif /* UNIV_SEARCH_DEBUG */
if (page_rec_is_infimum(rec)) {
/* The infimum record on a page cannot be in the result set,
and neither can a record lock be placed on it: we skip such
@ -3476,10 +3478,11 @@ rec_loop:
goto next_rec;
}
if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
if (page_rec_is_supremum(rec)) {
if (prebuilt->select_lock_type != LOCK_NONE
&& set_also_gap_locks) {
if (set_also_gap_locks
&& !srv_locks_unsafe_for_binlog
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record */
@ -3487,18 +3490,16 @@ rec_loop:
we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
if (!srv_locks_unsafe_for_binlog) {
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type,
LOCK_ORDINARY, thr);
if (err != DB_SUCCESS) {
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type,
LOCK_ORDINARY, thr);
goto lock_wait_or_error;
}
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
}
/* A page supremum record cannot be in the result set: skip
it now that we have placed a possible lock on it */
@ -3510,12 +3511,19 @@ rec_loop:
/* Do sanity checks in case our cursor has bumped into page
corruption */
next_offs = rec_get_next_offs(rec, comp);
if (next_offs >= UNIV_PAGE_SIZE
|| next_offs <
(ulint) (comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM)) {
if (page_rec_is_comp(rec)) {
next_offs = rec_get_next_offs(rec, TRUE);
if (UNIV_UNLIKELY(next_offs < PAGE_NEW_SUPREMUM)) {
goto wrong_offs;
}
} else {
next_offs = rec_get_next_offs(rec, FALSE);
if (UNIV_UNLIKELY(next_offs < PAGE_OLD_SUPREMUM)) {
goto wrong_offs;
}
}
if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) {
wrong_offs:
if (srv_force_recovery == 0 || moves_up == FALSE) {
ut_print_timestamp(stderr);
buf_page_print(buf_frame_align(rec));
@ -3528,7 +3536,7 @@ rec_loop:
fprintf(stderr,
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
"InnoDB: ",
(ulong) (rec - buf_frame_align(rec)),
(ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@ -3546,7 +3554,7 @@ rec_loop:
fprintf(stderr,
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
"InnoDB: ",
(ulong) (rec - buf_frame_align(rec)),
(ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@ -3561,13 +3569,13 @@ rec_loop:
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
if (srv_force_recovery > 0) {
if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
if (!rec_validate(rec, offsets)
|| !btr_index_rec_validate(rec, index, FALSE)) {
fprintf(stderr,
"InnoDB: Index corruption: rec offs %lu next offs %lu, page no %lu,\n"
"InnoDB: ",
(ulong) (rec - buf_frame_align(rec)),
(ulong) ut_align_offset(rec, UNIV_PAGE_SIZE),
(ulong) next_offs,
(ulong) buf_frame_get_page_no(rec));
dict_index_name_print(stderr, trx, index);
@ -3593,25 +3601,22 @@ rec_loop:
if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) {
if (prebuilt->select_lock_type != LOCK_NONE
&& set_also_gap_locks) {
if (set_also_gap_locks
&& !srv_locks_unsafe_for_binlog
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set */
if (srv_locks_unsafe_for_binlog == FALSE) {
err = sel_set_rec_lock(rec, index,
offsets,
err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type,
LOCK_GAP, thr);
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
}
btr_pcur_store_position(pcur, &mtr);
@ -3627,25 +3632,22 @@ rec_loop:
if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, offsets)) {
if (prebuilt->select_lock_type != LOCK_NONE
&& set_also_gap_locks) {
if (set_also_gap_locks
&& !srv_locks_unsafe_for_binlog
&& prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a gap lock on the index
record only if innodb_locks_unsafe_for_binlog
option is not set */
if (srv_locks_unsafe_for_binlog == FALSE) {
err = sel_set_rec_lock(rec, index,
offsets,
err = sel_set_rec_lock(rec, index, offsets,
prebuilt->select_lock_type,
LOCK_GAP, thr);
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
if (err != DB_SUCCESS) {
goto lock_wait_or_error;
}
}
btr_pcur_store_position(pcur, &mtr);
@ -3661,29 +3663,25 @@ rec_loop:
/* We are ready to look at a possible new index entry in the result
set: the cursor is now placed on a user record */
cons_read_requires_clust_rec = FALSE;
if (prebuilt->select_lock_type != LOCK_NONE) {
/* Try to place a lock on the index record; note that delete
marked records are a special case in a unique search. If there
is a non-delete marked record, then it is enough to lock its
existence with LOCK_REC_NOT_GAP. */
/* If innodb_locks_unsafe_for_binlog option is used,
we lock only the record, i.e., next-key locking is
not used. */
ulint lock_type;
if (!set_also_gap_locks
|| (unique_search && !rec_get_deleted_flag(rec, comp))) {
lock_type = LOCK_REC_NOT_GAP;
|| srv_locks_unsafe_for_binlog
|| (unique_search && !UNIV_UNLIKELY(rec_get_deleted_flag(
rec, page_rec_is_comp(rec))))) {
goto no_gap_lock;
} else {
/* If innodb_locks_unsafe_for_binlog option is used,
we lock only the record, i.e., next-key locking is
not used. */
if (srv_locks_unsafe_for_binlog) {
lock_type = LOCK_REC_NOT_GAP;
} else {
lock_type = LOCK_ORDINARY;
}
lock_type = LOCK_ORDINARY;
}
/* If we are doing a 'greater or equal than a primary key
@ -3703,7 +3701,7 @@ rec_loop:
&& dtuple_get_n_fields_cmp(search_tuple)
== dict_index_get_n_unique(index)
&& 0 == cmp_dtuple_rec(search_tuple, rec, offsets)) {
no_gap_lock:
lock_type = LOCK_REC_NOT_GAP;
}
@ -3731,7 +3729,7 @@ rec_loop:
high force recovery level set, we try to avoid crashes
by skipping this lookup */
if (srv_force_recovery < 5
if (UNIV_LIKELY(srv_force_recovery < 5)
&& !lock_clust_rec_cons_read_sees(rec, index,
offsets, trx->read_view)) {
@ -3762,13 +3760,15 @@ rec_loop:
have to look also into the clustered index: this
is necessary, because we can only get the undo
information via the clustered index record. */
cons_read_requires_clust_rec = TRUE;
/* Get the clustered index record if needed */
index_rec = rec;
ut_ad(index != clust_index);
goto requires_clust_rec;
}
}
if (rec_get_deleted_flag(rec, comp)
&& !cons_read_requires_clust_rec) {
if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, page_rec_is_comp(rec)))) {
/* The record is delete-marked: we can skip it if this is
not a consistent read which might see an earlier version
@ -3782,14 +3782,14 @@ rec_loop:
index_rec = rec;
/* Before and after the following "if" block, "offsets" will be
related to "rec", which may be in "index", a secondary index or
the clustered index ("clust_index"). However, after this "if" block,
"rec" may be pointing to "clust_rec" of "clust_index". */
ut_ad(rec_offs_validate(rec, index, offsets));
if (index != clust_index && (cons_read_requires_clust_rec
|| prebuilt->need_to_access_clustered)) {
if (index != clust_index && prebuilt->need_to_access_clustered) {
requires_clust_rec:
/* Before and after this "if" block, "offsets" will be
related to "rec", which may be in a secondary index "index" or
the clustered index ("clust_index"). However, after this
"if" block, "rec" may be pointing to
"clust_rec" of "clust_index". */
ut_ad(rec_offs_validate(rec, index, offsets));
/* It was a non-clustered index and we must fetch also the
clustered index record */
@ -3811,7 +3811,8 @@ rec_loop:
goto next_rec;
}
if (rec_get_deleted_flag(clust_rec, comp)) {
if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec,
page_rec_is_comp(clust_rec)))) {
/* The record is delete marked: we can skip it */
@ -3832,7 +3833,8 @@ rec_loop:
rec == clust_rec ? clust_index : index,
offsets));
if (prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD
if ((match_mode == ROW_SEL_EXACT
|| prebuilt->n_rows_fetched >= MYSQL_FETCH_CACHE_THRESHOLD)
&& prebuilt->select_lock_type == LOCK_NONE
&& !prebuilt->templ_contains_blob
&& !prebuilt->clust_index_was_generated
@ -3907,7 +3909,7 @@ next_rec:
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
if (mtr_has_extra_clust_latch) {
if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
/* We must commit mtr if we are moving to the next
non-clustered index record, because we could break the
latching order if we would access a different clustered
@ -3919,34 +3921,38 @@ next_rec:
mtr_has_extra_clust_latch = FALSE;
mtr_start(&mtr);
moved = sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
moves_up, &mtr);
if (moved) {
if (sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
moves_up, &mtr)) {
#ifdef UNIV_SEARCH_DEBUG
cnt++;
#endif /* UNIV_SEARCH_DEBUG */
goto rec_loop;
}
}
if (moves_up) {
moved = btr_pcur_move_to_next(pcur, &mtr);
} else {
moved = btr_pcur_move_to_prev(pcur, &mtr);
}
if (UNIV_UNLIKELY(!btr_pcur_move_to_next(pcur, &mtr))) {
not_moved:
btr_pcur_store_position(pcur, &mtr);
if (!moved) {
btr_pcur_store_position(pcur, &mtr);
if (match_mode != 0) {
err = DB_RECORD_NOT_FOUND;
} else {
err = DB_END_OF_INDEX;
}
if (match_mode != 0) {
err = DB_RECORD_NOT_FOUND;
} else {
err = DB_END_OF_INDEX;
goto normal_return;
}
} else {
if (UNIV_UNLIKELY(!btr_pcur_move_to_prev(pcur, &mtr))) {
goto not_moved;
}
goto normal_return;
}
#ifdef UNIV_SEARCH_DEBUG
cnt++;
#endif /* UNIV_SEARCH_DEBUG */
goto rec_loop;
@ -3964,11 +3970,10 @@ lock_wait_or_error:
que_thr_stop_for_mysql(thr);
thr->lock_state= QUE_THR_LOCK_ROW;
was_lock_wait = row_mysql_handle_errors(&err, trx, thr, NULL);
thr->lock_state= QUE_THR_LOCK_NOLOCK;
thr->lock_state = QUE_THR_LOCK_ROW;
if (was_lock_wait) {
if (row_mysql_handle_errors(&err, trx, thr, NULL)) {
thr->lock_state = QUE_THR_LOCK_NOLOCK;
mtr_start(&mtr);
sel_restore_position_for_mysql(BTR_SEARCH_LEAF, pcur,
@ -3978,9 +3983,13 @@ lock_wait_or_error:
goto rec_loop;
}
thr->lock_state = QUE_THR_LOCK_NOLOCK;
#ifdef UNIV_SEARCH_DEBUG
/* fputs("Using ", stderr);
dict_index_name_print(stderr, index);
fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
#endif /* UNIV_SEARCH_DEBUG */
goto func_exit;
normal_return:
@ -3995,16 +4004,18 @@ normal_return:
err = DB_SUCCESS;
}
#ifdef UNIV_SEARCH_DEBUG
/* fputs("Using ", stderr);
dict_index_name_print(stderr, index);
fprintf(stderr, " cnt %lu ret value %lu err\n", cnt, err); */
#endif /* UNIV_SEARCH_DEBUG */
if (err == DB_SUCCESS) {
srv_n_rows_read++;
}
func_exit:
trx->op_info = "";
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);

View file

@ -190,7 +190,7 @@ row_undo_search_clust_to_pcur(
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(ret);

View file

@ -815,9 +815,10 @@ row_upd_build_difference_binary(
goto skip_compare;
}
extern_bit = rec_offs_nth_extern(offsets, i);
extern_bit = upd_ext_vec_contains(ext_vec, n_ext_vec, i);
if (extern_bit != upd_ext_vec_contains(ext_vec, n_ext_vec, i)
if (UNIV_UNLIKELY(extern_bit ==
!rec_offs_nth_extern(offsets, i))
|| !dfield_data_is_binary_equal(dfield, len, data)) {
upd_field = upd_get_nth_field(update, n_diff);
@ -826,12 +827,8 @@ row_upd_build_difference_binary(
upd_field_set_field_no(upd_field, i, index, trx);
if (upd_ext_vec_contains(ext_vec, n_ext_vec, i)) {
upd_field->extern_storage = TRUE;
} else {
upd_field->extern_storage = FALSE;
}
upd_field->extern_storage = extern_bit;
n_diff++;
}
skip_compare:
@ -1224,7 +1221,7 @@ row_upd_store_row(
node->n_ext_vec = btr_push_update_extern_fields(node->ext_vec,
offsets, update);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
}
@ -1270,7 +1267,7 @@ row_upd_sec_index_entry(
rec = btr_cur_get_rec(btr_cur);
if (!found) {
if (UNIV_UNLIKELY(!found)) {
fputs("InnoDB: error in sec index entry update in\n"
"InnoDB: ", stderr);
dict_index_name_print(stderr, trx, index);
@ -1423,7 +1420,7 @@ row_upd_clust_rec_by_insert(
index, thr, mtr);
if (err != DB_SUCCESS) {
mtr_commit(mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@ -1549,7 +1546,7 @@ row_upd_clust_rec(
rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
big_rec, mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
mtr_commit(mtr);
@ -1719,7 +1716,7 @@ row_upd_clust_step(
node->index = dict_table_get_next_index(index);
}
exit_func:
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
@ -1736,7 +1733,7 @@ row_upd_clust_step(
row_upd_eval_new_vals(node->update);
}
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@ -2016,7 +2013,7 @@ row_upd_in_place_in_select(
btr_pcur_get_rec(pcur), btr_cur->index, offsets_,
ULINT_UNDEFINED, &heap),
UT_LIST_GET_FIRST(node->columns));
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
row_upd_eval_new_vals(node->update);

View file

@ -57,11 +57,11 @@ row_vers_impl_x_locked_off_kernel(
dtuple_t* entry = NULL; /* assignment to eliminate compiler
warning */
trx_t* trx;
ibool vers_del;
ibool rec_del;
ulint vers_del;
ulint rec_del;
ulint err;
mtr_t mtr;
ibool comp;
ulint comp;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&kernel_mutex));
@ -121,10 +121,10 @@ row_vers_impl_x_locked_off_kernel(
goto exit_func;
}
comp = index->table->comp;
comp = page_rec_is_comp(rec);
ut_ad(index->table == clust_index->table);
ut_ad(comp == page_is_comp(buf_frame_align(rec)));
ut_ad(comp == page_is_comp(buf_frame_align(clust_rec)));
ut_ad(!!comp == index->table->comp);
ut_ad(!comp == !page_rec_is_comp(clust_rec));
/* We look up if some earlier version, which was modified by the trx_id
transaction, of the clustered index record would require rec to be in
@ -310,7 +310,7 @@ row_vers_old_has_index_entry(
dtuple_t* row;
dtuple_t* entry;
ulint err;
ibool comp;
ulint comp;
ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
|| mtr_memo_contains(mtr, buf_block_align(rec),
@ -322,8 +322,8 @@ row_vers_old_has_index_entry(
clust_index = dict_table_get_first_index(index->table);
comp = index->table->comp;
ut_ad(comp == page_is_comp(buf_frame_align(rec)));
comp = page_rec_is_comp(rec);
ut_ad(!index->table->comp == !comp);
heap = mem_heap_create(1024);
clust_offsets = rec_get_offsets(rec, clust_index, NULL,
ULINT_UNDEFINED, &heap);

View file

@ -1040,7 +1040,9 @@ innobase_start_or_create_for_mysql(void)
srv_start_has_been_called = TRUE;
#ifdef UNIV_DEBUG
log_do_write = TRUE;
#endif /* UNIV_DEBUG */
/* yydebug = TRUE; */
srv_is_being_started = TRUE;
@ -1554,8 +1556,9 @@ NetWare. */
os_thread_create(&srv_master_thread, NULL, thread_ids + 1 +
SRV_MAX_N_IO_THREADS);
#ifdef UNIV_DEBUG
/* buf_debug_prints = TRUE; */
#endif /* UNIV_DEBUG */
sum_of_data_file_sizes = 0;
for (i = 0; i < srv_n_data_files; i++) {

View file

@ -1136,8 +1136,12 @@ sync_thread_add_level(
} else if (level == SYNC_DICT_HEADER) {
ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER));
} else if (level == SYNC_DICT) {
#ifdef UNIV_DEBUG
ut_a(buf_debug_prints
|| sync_thread_levels_g(array, SYNC_DICT));
#else /* UNIV_DEBUG */
ut_a(sync_thread_levels_g(array, SYNC_DICT));
#endif /* UNIV_DEBUG */
} else {
ut_error;
}

View file

@ -1134,7 +1134,7 @@ trx_undo_report_row_operation(
mutex_exit(&(trx->undo_mutex));
mtr_commit(&mtr);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(DB_OUT_OF_FILE_SPACE);
@ -1153,7 +1153,7 @@ trx_undo_report_row_operation(
*roll_ptr = trx_undo_build_roll_ptr(is_insert, rseg->id, page_no,
offset);
if (heap) {
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(DB_SUCCESS);

View file

@ -1237,10 +1237,12 @@ trx_finish_rollback_off_kernel(
return;
}
#ifdef UNIV_DEBUG
if (lock_print_waits) {
fprintf(stderr, "Trx %lu rollback finished\n",
(ulong) ut_dulint_get_low(trx->id));
}
#endif /* UNIV_DEBUG */
trx_commit_off_kernel(trx);

View file

@ -158,8 +158,6 @@ trx_create(
trx->n_tickets_to_enter_innodb = 0;
trx->auto_inc_lock = NULL;
trx->n_lock_table_exp = 0;
trx->n_lock_table_transactional = 0;
trx->read_view_heap = mem_heap_create(256);
trx->read_view = NULL;
@ -309,8 +307,6 @@ trx_free(
ut_a(!trx->has_search_latch);
ut_a(!trx->auto_inc_lock);
ut_a(!trx->n_lock_table_exp);
ut_a(!trx->n_lock_table_transactional);
ut_a(trx->dict_operation_lock_mode == 0);
@ -1711,12 +1707,6 @@ trx_print(
(ulong) trx->mysql_n_tables_locked);
}
if (trx->n_lock_table_transactional > 0 || trx->n_lock_table_exp > 0) {
fprintf(f, "mysql explicit table locks %lu, transactional table locks %lu\n",
(ulong) trx->n_lock_table_exp,
(ulong) trx->n_lock_table_transactional);
}
newline = TRUE;
switch (trx->que_state) {

View file

@ -8,8 +8,11 @@ Created 1/30/1994 Heikki Tuuri
#include "univ.i"
#if defined(__GNUC__) && (__GNUC__ > 2)
#else
/* This is used to eliminate compiler warnings */
ulint ut_dbg_zero = 0;
#endif
/* If this is set to TRUE all threads will stop into the next assertion
and assert */
@ -19,21 +22,69 @@ ibool panic_shutdown = FALSE; /* This is set to TRUE when on NetWare there
happens an InnoDB assertion failure or other
fatal error condition that requires an
immediate shutdown. */
#endif
#else /* __NETWARE__ */
/* Null pointer used to generate memory trap */
ulint* ut_dbg_null_ptr = NULL;
#endif /* __NETWARE__ */
const char* ut_dbg_msg_assert_fail =
"InnoDB: Assertion failure in thread %lu in file %s line %lu\n";
const char* ut_dbg_msg_trap =
/*****************************************************************
Report a failed assertion. */
void
ut_dbg_assertion_failed(
/*====================*/
const char* expr, /* in: the failed assertion (optional) */
const char* file, /* in: source file containing the assertion */
ulint line) /* in: line number of the assertion */
{
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: Assertion failure in thread %lu"
" in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
if (expr) {
fprintf(stderr,
"InnoDB: Failing assertion: %s\n", expr);
}
fputs(
"InnoDB: We intentionally generate a memory trap.\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com.\n"
"InnoDB: If you get repeated assertion failures or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n"
"InnoDB: about forcing recovery.\n";
"InnoDB: about forcing recovery.\n", stderr);
ut_dbg_stop_threads = TRUE;
}
const char* ut_dbg_msg_stop =
"InnoDB: Thread %lu stopped in file %s line %lu\n";
#ifdef __NETWARE__
/*****************************************************************
Shut down MySQL/InnoDB after assertion failure. */
void
ut_dbg_panic(void)
/*==============*/
{
if (!panic_shutdown) {
panic_shutdown = TRUE;
innobase_shutdown_for_mysql();
}
exit(1);
}
#else /* __NETWARE__ */
/*****************************************************************
Stop a thread after assertion failure. */
void
ut_dbg_stop_thread(
/*===============*/
const char* file,
ulint line)
{
fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
os_thread_sleep(1000000000);
}
#endif /* __NETWARE__ */

View file

@ -410,7 +410,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
Hack: instead of init_queue, we'll use reinit queue to be able
to alloc queue with alloc_root()
*/
res=ftb->queue.max_elements=1+query_len/(min(ft_min_word_len,2)+1);
res=ftb->queue.max_elements=1+query_len/2;
if (!(ftb->queue.root=
(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*))))
goto err;

View file

@ -4,6 +4,7 @@
# and is part of the translation of the Bourne shell script with the
# same name.
use File::Basename;
use strict;
sub collect_test_cases ($);
@ -39,6 +40,7 @@ sub collect_test_cases ($) {
if ( @::opt_cases )
{
foreach my $tname ( @::opt_cases ) { # Run in specified order, no sort
$tname= basename($tname, ".test");
my $elem= "$tname.test";
if ( ! -f "$testdir/$elem")
{
@ -161,52 +163,73 @@ sub collect_one_test_case($$$$$) {
my $slave_sh= "$testdir/$tname-slave.sh";
my $disabled= "$testdir/$tname.disabled";
$tinfo->{'master_opt'}= ["--default-time-zone=+3:00"];
$tinfo->{'slave_opt'}= ["--default-time-zone=+3:00"];
$tinfo->{'master_opt'}= $::glob_win32 ? ["--default-time-zone=+3:00"] : [];
$tinfo->{'slave_opt'}= $::glob_win32 ? ["--default-time-zone=+3:00"] : [];
$tinfo->{'slave_mi'}= [];
if ( -f $master_opt_file )
{
$tinfo->{'master_restart'}= 1; # We think so for now
# This is a dirty hack from old mysql-test-run, we use the opt file
# to flag other things as well, it is not a opt list at all
$tinfo->{'master_opt'}= mtr_get_opts_from_file($master_opt_file);
foreach my $opt (@{$tinfo->{'master_opt'}})
MASTER_OPT:
{
my $value;
my $master_opt= mtr_get_opts_from_file($master_opt_file);
$value= mtr_match_prefix($opt, "--timezone=");
if ( defined $value )
foreach my $opt ( @$master_opt )
{
$tinfo->{'timezone'}= $value;
$tinfo->{'master_opt'}= [];
$tinfo->{'master_restart'}= 0;
last;
}
my $value;
$value= mtr_match_prefix($opt, "--result-file=");
# This is a dirty hack from old mysql-test-run, we use the opt
# file to flag other things as well, it is not a opt list at
# all
if ( defined $value )
{
$tinfo->{'result_file'}= "r/$value.result";
if ( $::opt_result_ext and $::opt_record or
-f "$tinfo->{'result_file'}$::opt_result_ext")
$value= mtr_match_prefix($opt, "--timezone=");
if ( defined $value )
{
$tinfo->{'result_file'}.= $::opt_result_ext;
$tinfo->{'timezone'}= $value;
$tinfo->{'skip'}= 1 if $::glob_win32; # FIXME server unsets TZ
last MASTER_OPT;
}
$tinfo->{'master_opt'}= [];
$tinfo->{'master_restart'}= 0;
last;
$value= mtr_match_prefix($opt, "--result-file=");
if ( defined $value )
{
$tinfo->{'result_file'}= "r/$value.result";
if ( $::opt_result_ext and $::opt_record or
-f "$tinfo->{'result_file'}$::opt_result_ext")
{
$tinfo->{'result_file'}.= $::opt_result_ext;
}
$tinfo->{'master_restart'}= 0;
last MASTER_OPT;
}
# If we set default time zone, remove the one we have
$value= mtr_match_prefix($opt, "--default-time-zone=");
if ( defined $value )
{
$tinfo->{'master_opt'}= [];
}
}
# Ok, this was a real option list, add it
push(@{$tinfo->{'master_opt'}}, @$master_opt);
}
}
if ( -f $slave_opt_file )
{
$tinfo->{'slave_opt'}= mtr_get_opts_from_file($slave_opt_file);
$tinfo->{'slave_restart'}= 1;
my $slave_opt= mtr_get_opts_from_file($slave_opt_file);
foreach my $opt ( @$slave_opt )
{
# If we set default time zone, remove the one we have
my $value= mtr_match_prefix($opt, "--default-time-zone=");
$tinfo->{'slave_opt'}= [] if defined $value;
}
push(@{$tinfo->{'slave_opt'}}, @$slave_opt);
}
if ( -f $slave_mi_file )

View file

@ -9,6 +9,9 @@ use strict;
sub mtr_full_hostname ();
sub mtr_init_args ($);
sub mtr_add_arg ($$);
sub mtr_path_exists(@);
sub mtr_script_exists(@);
sub mtr_exe_exists(@);
##############################################################################
#
@ -47,4 +50,53 @@ sub mtr_add_arg ($$) {
push(@$args, sprintf($format, @fargs));
}
##############################################################################
sub mtr_path_exists (@) {
foreach my $path ( @_ )
{
return $path if -e $path;
}
if ( @_ == 1 )
{
mtr_error("Could not find $_[0]");
}
else
{
mtr_error("Could not find any of " . join(" ", @_));
}
}
sub mtr_script_exists (@) {
foreach my $path ( @_ )
{
return $path if -x $path;
}
if ( @_ == 1 )
{
mtr_error("Could not find $_[0]");
}
else
{
mtr_error("Could not find any of " . join(" ", @_));
}
}
sub mtr_exe_exists (@) {
foreach my $path ( @_ )
{
$path.= ".exe" if $::opt_win32;
return $path if -x $path;
}
if ( @_ == 1 )
{
mtr_error("Could not find $_[0]");
}
else
{
mtr_error("Could not find any of " . join(" ", @_));
}
}
1;

View file

@ -38,6 +38,13 @@ sub mtr_show_failed_diff ($) {
my $result_file= "r/$tname.result";
my $eval_file= "r/$tname.eval";
if ( $::opt_suite ne "main" )
{
$reject_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$reject_file";
$result_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$result_file";
$eval_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$eval_file";
}
if ( -f $eval_file )
{
$result_file= $eval_file;

View file

@ -264,6 +264,7 @@ our $opt_warnings;
our $opt_udiff;
our $opt_skip_ndbcluster;
our $opt_with_ndbcluster;
our $opt_with_openssl;
@ -463,6 +464,7 @@ sub command_line_setup () {
# Control what test suites or cases to run
'force' => \$opt_force,
'with-ndbcluster' => \$opt_with_ndbcluster,
'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster,
'do-test=s' => \$opt_do_test,
'suite=s' => \$opt_suite,
'skip-rpl' => \$opt_skip_rpl,
@ -662,6 +664,11 @@ sub command_line_setup () {
$opt_ndbconnectstring= "host=localhost:$opt_ndbcluster_port";
}
if ( $opt_skip_ndbcluster )
{
$opt_with_ndbcluster= 0;
}
# FIXME
#if ( $opt_valgrind or $opt_valgrind_all )
@ -763,146 +770,83 @@ sub executable_setup () {
if ( $opt_source_dist )
{
if ( $glob_win32 )
{
$path_client_bindir= mtr_path_exists("$glob_basedir/client_release");
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt");
$path_language= mtr_path_exists("$glob_basedir/share/english/");
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets");
}
else
{
$path_client_bindir= mtr_path_exists("$glob_basedir/client");
$exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld");
$path_language= mtr_path_exists("$glob_basedir/sql/share/english/");
$path_charsetsdir= mtr_path_exists("$glob_basedir/sql/share/charsets");
}
if ( $glob_use_embedded_server )
{
if ( -f "$glob_basedir/libmysqld/examples/mysqltest" )
{
$exe_mysqltest= "$glob_basedir/libmysqld/examples/mysqltest";
}
else
{
mtr_error("Can't find embedded server 'mysqltest'");
}
my $path_examples= "$glob_basedir/libmysqld/examples";
$exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest");
$exe_mysql_client_test=
"$glob_basedir/libmysqld/examples/mysql_client_test_embedded";
mtr_exe_exists("$path_examples/mysql_client_test_embedded");
}
else
{
if ( -f "$glob_basedir/client/.libs/lt-mysqltest" )
{
$exe_mysqltest= "$glob_basedir/client/.libs/lt-mysqltest";
}
elsif ( -f "$glob_basedir/client/.libs/mysqltest" )
{
$exe_mysqltest= "$glob_basedir/client/.libs/mysqltest";
}
else
{
$exe_mysqltest= "$glob_basedir/client/mysqltest";
}
$exe_mysqltest= mtr_exe_exists("$glob_basedir/client/mysqltest");
$exe_mysql_client_test=
"$glob_basedir/tests/mysql_client_test";
mtr_exe_exists("$glob_basedir/tests/mysql_client_test");
}
if ( -f "$glob_basedir/client/.libs/mysqldump" )
{
$exe_mysqldump= "$glob_basedir/client/.libs/mysqldump";
}
else
{
$exe_mysqldump= "$glob_basedir/client/mysqldump";
}
if ( -f "$glob_basedir/client/.libs/mysqlshow" )
{
$exe_mysqlshow= "$glob_basedir/client/.libs/mysqlshow";
}
else
{
$exe_mysqlshow= "$glob_basedir/client/mysqlshow";
}
if ( -f "$glob_basedir/client/.libs/mysqlbinlog" )
{
$exe_mysqlbinlog= "$glob_basedir/client/.libs/mysqlbinlog";
}
else
{
$exe_mysqlbinlog= "$glob_basedir/client/mysqlbinlog";
}
$path_client_bindir= "$glob_basedir/client";
$exe_mysqld= "$glob_basedir/sql/mysqld";
$exe_mysqladmin= "$path_client_bindir/mysqladmin";
$exe_mysql= "$path_client_bindir/mysql";
$exe_mysql_fix_system_tables= "$glob_basedir/scripts/mysql_fix_privilege_tables";
$path_language= "$glob_basedir/sql/share/english/";
$path_charsetsdir= "$glob_basedir/sql/share/charsets";
$path_ndb_tools_dir= "$glob_basedir/ndb/tools";
$exe_ndb_mgm= "$glob_basedir/ndb/src/mgmclient/ndb_mgm";
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
$exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
$exe_mysql_fix_system_tables=
mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables");
$path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools");
$exe_ndb_mgm= "$glob_basedir/ndb/src/mgmclient/ndb_mgm";
}
else
{
my $path_tests_bindir= "$glob_basedir/tests";
$path_client_bindir= mtr_path_exists("$glob_basedir/bin");
$exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
$exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
$exe_mysql_fix_system_tables=
mtr_script_exists("$path_client_bindir/mysql_fix_privilege_tables");
$path_client_bindir= "$glob_basedir/bin";
$exe_mysqltest= "$path_client_bindir/mysqltest";
$exe_mysqldump= "$path_client_bindir/mysqldump";
$exe_mysqlshow= "$path_client_bindir/mysqlshow";
$exe_mysqlbinlog= "$path_client_bindir/mysqlbinlog";
$exe_mysqladmin= "$path_client_bindir/mysqladmin";
$exe_mysql= "$path_client_bindir/mysql";
$exe_mysql_fix_system_tables= "$path_client_bindir/mysql_fix_privilege_tables";
if ( -d "$glob_basedir/share/mysql/english" )
{
$path_language ="$glob_basedir/share/mysql/english/";
$path_charsetsdir ="$glob_basedir/share/mysql/charsets";
}
else
{
$path_language ="$glob_basedir/share/english/";
$path_charsetsdir ="$glob_basedir/share/charsets";
}
if ( -x "$glob_basedir/libexec/mysqld" )
{
$exe_mysqld= "$glob_basedir/libexec/mysqld";
}
else
{
$exe_mysqld= "$glob_basedir/bin/mysqld";
}
$path_language= mtr_path_exists("$glob_basedir/share/mysql/english/",
"$glob_basedir/share/english/");
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets",
"$glob_basedir/share/charsets");
$exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld",
"$glob_basedir/bin/mysqld");
if ( $glob_use_embedded_server )
{
if ( -f "$path_client_bindir/mysqltest_embedded" )
{
# FIXME valgrind?
$exe_mysqltest="$path_client_bindir/mysqltest_embedded";
}
else
{
mtr_error("Cannot find embedded server 'mysqltest_embedded'");
}
if ( -d "$path_tests_bindir/mysql_client_test_embedded" )
{
$exe_mysql_client_test=
"$path_tests_bindir/mysql_client_test_embedded";
}
else
{
$exe_mysql_client_test=
"$path_client_bindir/mysql_client_test_embedded";
}
$exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest_embedded");
$exe_mysql_client_test=
mtr_exe_exists("$glob_basedir/tests/mysql_client_test_embedded",
"$path_client_bindir/mysql_client_test_embedded");
}
else
{
$exe_mysqltest="$path_client_bindir/mysqltest";
$exe_mysql_client_test="$path_client_bindir/mysql_client_test";
$exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
$exe_mysql_client_test=
mtr_exe_exists("$path_client_bindir/mysql_client_test");
}
$path_ndb_tools_dir= "$glob_basedir/bin";
$exe_ndb_mgm= "$glob_basedir/bin/ndb_mgm";
}
if ( ! $exe_master_mysqld )
{
$exe_master_mysqld= $exe_mysqld;
}
if ( ! $exe_slave_mysqld )
{
$exe_slave_mysqld= $exe_mysqld;
}
$exe_master_mysqld= $exe_master_mysqld || $exe_mysqld;
$exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld;
$path_ndb_backup_dir=
"$opt_vardir/ndbcluster-$opt_ndbcluster_port";
@ -921,15 +865,19 @@ sub executable_setup () {
sub environment_setup () {
# --------------------------------------------------------------------------
# Set LD_LIBRARY_PATH if we are using shared libraries
# We might not use a standard installation directory, like /usr/lib.
# Set LD_LIBRARY_PATH to make sure we find our installed libraries.
# --------------------------------------------------------------------------
$ENV{'LD_LIBRARY_PATH'}=
"$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
$ENV{'DYLD_LIBRARY_PATH'}=
"$glob_basedir/lib:$glob_basedir/libmysql/.libs" .
($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : "");
unless ( $opt_source_dist )
{
$ENV{'LD_LIBRARY_PATH'}=
"$glob_basedir/lib" .
($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : "");
$ENV{'DYLD_LIBRARY_PATH'}=
"$glob_basedir/lib" .
($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : "");
}
# --------------------------------------------------------------------------
# Also command lines in .opt files may contain env vars
@ -1020,11 +968,6 @@ sub kill_and_cleanup () {
mtr_report("Removing Stale Files");
if ( -l $opt_vardir and ! unlink($opt_vardir) )
{
mtr_error("Can't remove soft link \"$opt_vardir\"");
}
rmtree("$opt_vardir/log");
rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port");
rmtree("$opt_vardir/run");
@ -1719,6 +1662,11 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--local-infile", $prefix);
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$master->[$idx]->{'path_myddir'});
if ( $opt_skip_ndbcluster )
{
mtr_add_arg($args, "%s--skip-ndbcluster", $prefix);
}
}
if ( $type eq 'slave' )
@ -1860,19 +1808,11 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--rpl-recovery-rank=1", $prefix);
mtr_add_arg($args, "%s--init-rpl-role=master", $prefix);
}
else
elsif ( $type eq 'master' )
{
mtr_add_arg($args, "%s--exit-info=256", $prefix);
mtr_add_arg($args, "%s--open-files-limit=1024", $prefix);
if ( $type eq 'master' )
{
mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'});
}
if ( $type eq 'slave' )
{
mtr_add_arg($args, "%s--log=%s", $prefix, $slave->[0]->{'path_mylog'});
}
mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'});
}
return $args;

View file

@ -339,7 +339,7 @@ insert into t2 values (3, 1, 'xxbuz');
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
t1_id name t2_id t1_id name
1 data1 1 1 xxfoo
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
select * from t2 where match name against ('*a*b*c*d*e*f*' in boolean mode);
t2_id t1_id name
drop table t1,t2;
create table t1 (a text, fulltext key (a));

View file

@ -753,3 +753,12 @@ SELECT DISTINCT a, b FROM t1 GROUP BY 'const';
a b
1 2
DROP TABLE t1;
CREATE TABLE t1 (id INT, dt DATETIME);
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f;
f id
20050501123000 1
DROP TABLE t1;

View file

@ -1779,7 +1779,7 @@ Variable_name Value
innodb_sync_spin_loops 20
show variables like "innodb_thread_concurrency";
Variable_name Value
innodb_thread_concurrency 8
innodb_thread_concurrency 20
set global innodb_thread_concurrency=1000;
show variables like "innodb_thread_concurrency";
Variable_name Value

View file

@ -253,9 +253,9 @@ insert into t2 values (3, 1, 'xxbuz');
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
#
# bug with many short (< ft_min_word_len) words in boolean search
# Bug #7858: bug with many short (< ft_min_word_len) words in boolean search
#
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
select * from t2 where match name against ('*a*b*c*d*e*f*' in boolean mode);
drop table t1,t2;
#

View file

@ -567,7 +567,7 @@ show warnings;
drop table t1, t2;
#
# Test for bug #8614: GROUP BY 'const with DISTINCT
# Test for bug #8614: GROUP BY 'const' with DISTINCT
#
CREATE TABLE t1 (a int, b int);
@ -576,3 +576,16 @@ SELECT a, b FROM t1 GROUP BY 'const';
SELECT DISTINCT a, b FROM t1 GROUP BY 'const';
DROP TABLE t1;
#
# Test for bug #11385: GROUP BY for datetime converted to decimals
#
CREATE TABLE t1 (id INT, dt DATETIME);
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
INSERT INTO t1 VALUES ( 1, '2005-05-01 12:30:00' );
SELECT dt DIV 1 AS f, id FROM t1 GROUP BY f;
DROP TABLE t1;

View file

@ -111,8 +111,8 @@ DEFS = -DMYSQL_SERVER \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
@DEFS@
# Don't put lex_hash.h in BUILT_SOURCES as this will give infinite recursion
BUILT_SOURCES = sql_yacc.cc sql_yacc.h
BUILT_SOURCES = sql_yacc.cc sql_yacc.h lex_hash.h
EXTRA_DIST = udf_example.cc $(BUILT_SOURCES)
DISTCLEANFILES = lex_hash.h
AM_YFLAGS = -d
@ -131,9 +131,6 @@ link_sources: mysql_tzinfo_to_sql.cc
rm -f my_time.c
@LN_CP_F@ ../sql-common/my_time.c my_time.c
gen_lex_hash.o: gen_lex_hash.cc lex.h
$(CXXCOMPILE) -c $(INCLUDES) $<
mysql_tzinfo_to_sql.o: $(mysql_tzinfo_to_sql_SOURCES)
$(CXXCOMPILE) -c $(INCLUDES) -DTZINFO2SQL $<
@ -148,13 +145,9 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
@echo "If it fails, re-run configure with --with-low-memory"
$(CXXCOMPILE) $(LM_CFLAGS) -c $<
lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h
$(MAKE) gen_lex_hash$(EXEEXT)
lex_hash.h: gen_lex_hash$(EXEEXT)
./gen_lex_hash$(EXEEXT) > $@
# Hack to ensure that lex_hash.h is built early
sql_lex.o: lex_hash.h
# For testing of udf_example.so; Works on platforms with gcc
# (This is not part of our build process but only provided as an example)
udf_example.so: udf_example.cc

View file

@ -25,6 +25,7 @@
#endif
#define NOT_FIXED_DEC 31
#define DATETIME_DEC 6
class Send_field;
class Protocol;
@ -941,6 +942,7 @@ public:
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
#endif
enum Item_result cmp_type () const { return INT_RESULT; }
uint decimals() const { return DATETIME_DEC; }
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr);

View file

@ -146,8 +146,7 @@ long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_buffer_pool_awe_mem_mb,
innobase_buffer_pool_size, innobase_additional_mem_pool_size,
innobase_file_io_threads, innobase_lock_wait_timeout,
innobase_thread_concurrency, innobase_force_recovery,
innobase_open_files;
innobase_force_recovery, innobase_open_files;
/* The default values for the following char* start-up parameters
are determined in innobase_init below: */
@ -327,7 +326,7 @@ innodb_srv_conc_enter_innodb(
/*=========================*/
trx_t* trx) /* in: transaction handle */
{
if (srv_thread_concurrency >= 500) {
if (UNIV_LIKELY(srv_thread_concurrency >= 20)) {
return;
}
@ -344,7 +343,7 @@ innodb_srv_conc_exit_innodb(
/*========================*/
trx_t* trx) /* in: transaction handle */
{
if (srv_thread_concurrency >= 500) {
if (UNIV_LIKELY(srv_thread_concurrency >= 20)) {
return;
}
@ -1044,6 +1043,18 @@ mysql_get_identifier_quote_char(
name, (int) namelen));
}
/**************************************************************************
Determines if the currently running transaction has been interrupted. */
extern "C"
ibool
trx_is_interrupted(
/*===============*/
/* out: TRUE if interrupted */
trx_t* trx) /* in: transaction */
{
return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed);
}
/**************************************************************************
Obtain a pointer to the MySQL THD object, as in current_thd(). This
definition must match the one in sql/ha_innodb.cc! */
@ -1302,8 +1313,8 @@ innobase_init(void)
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
data_mysql_latin1_swedish_charset_coll =
(ulint)my_charset_latin1.number;
ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL ==
my_charset_latin1.number);
/* Store the latin1_swedish_ci character ordering table to InnoDB. For
non-latin1_swedish_ci charsets we use the MySQL comparison functions,
@ -2867,6 +2878,8 @@ build_template(
ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE;
ulint i;
/* byte offset of the end of last requested column */
ulint mysql_prefix_len = 0;
if (prebuilt->select_lock_type == LOCK_X) {
/* We always retrieve the whole clustered index record if we
@ -2987,6 +3000,11 @@ build_template(
get_field_offset(table, field);
templ->mysql_col_len = (ulint) field->pack_length();
if (mysql_prefix_len < templ->mysql_col_offset
+ templ->mysql_col_len) {
mysql_prefix_len = templ->mysql_col_offset
+ templ->mysql_col_len;
}
templ->type = index->table->cols[i].type.mtype;
templ->mysql_type = (ulint)field->type();
@ -3009,6 +3027,7 @@ skip_field:
}
prebuilt->n_template = n_requested_fields;
prebuilt->mysql_prefix_len = mysql_prefix_len;
if (index != clust_index && prebuilt->need_to_access_clustered) {
/* Change rec_field_no's to correspond to the clustered index
@ -3080,7 +3099,7 @@ ha_innobase::write_row(
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
dict_table_t* src_table;
ibool mode;
ulint mode;
num_write_row = 0;
@ -5991,7 +6010,7 @@ ha_innobase::external_lock(
ulint error;
error = row_lock_table_for_mysql(prebuilt,
NULL, LOCK_TABLE_EXP);
NULL, 0);
if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql(
@ -6011,9 +6030,6 @@ ha_innobase::external_lock(
trx->n_mysql_tables_in_use--;
prebuilt->mysql_has_locked = FALSE;
if (trx->n_lock_table_exp) {
row_unlock_tables_for_mysql(trx);
}
/* If the MySQL lock count drops to zero we know that the current SQL
statement has ended */
@ -6055,7 +6071,7 @@ user issued query LOCK TABLES..WHERE ENGINE = InnoDB. */
int
ha_innobase::transactional_table_lock(
/*==================================*/
/* out: 0 */
/* out: error code */
THD* thd, /* in: handle to the user thread */
int lock_type) /* in: lock type */
{
@ -6119,8 +6135,7 @@ ha_innobase::transactional_table_lock(
if (thd->in_lock_tables && thd->variables.innodb_table_locks) {
ulint error = DB_SUCCESS;
error = row_lock_table_for_mysql(prebuilt,NULL,
LOCK_TABLE_TRANSACTIONAL);
error = row_lock_table_for_mysql(prebuilt, NULL, 0);
if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql((int) error, user_thd);

View file

@ -218,7 +218,7 @@ extern long innobase_log_file_size, innobase_log_buffer_size;
extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
extern long innobase_buffer_pool_awe_mem_mb;
extern long innobase_file_io_threads, innobase_lock_wait_timeout;
extern long innobase_force_recovery, innobase_thread_concurrency;
extern long innobase_force_recovery;
extern long innobase_open_files;
extern char *innobase_data_home_dir, *innobase_data_file_path;
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;

View file

@ -5238,7 +5238,7 @@ log and this option does nothing anymore.",
{"innodb_thread_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
"Helps in performance tuning in heavily concurrent environments.",
(gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency,
0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0},
0, GET_LONG, REQUIRED_ARG, 20, 1, 1000, 0, 1, 0},
{"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY,
"Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0"
" disable a sleep",

View file

@ -425,6 +425,7 @@ int vio_close_pipe(Vio * vio)
void vio_ignore_timeout(Vio *vio __attribute__((unused)),
uint which __attribute__((unused)),
uint timeout __attribute__((unused)))
{
}