summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <tulin@dl145b.mysql.com>2005-06-21 08:49:21 +0200
committerunknown <tulin@dl145b.mysql.com>2005-06-21 08:49:21 +0200
commitcee82bca2970bfe36e17a84cad27a238900f7f81 (patch)
tree021f00d0d8d4e312b7cc20166e879b5052187631 /storage
parentca2e8ed7f372351fbf290445b2f5afd4840d7b45 (diff)
parentbf6a86afcafc559aed642d10da692c94584d258b (diff)
downloadmariadb-git-cee82bca2970bfe36e17a84cad27a238900f7f81.tar.gz
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into dl145b.mysql.com:/home/ndbdev/tomas/mysql-5.1 sql/ha_innodb.cc: Auto merged sql/ha_innodb.h: Auto merged sql/mysqld.cc: Auto merged storage/innobase/btr/btr0btr.c: Auto merged storage/innobase/btr/btr0cur.c: Auto merged storage/innobase/btr/btr0pcur.c: Auto merged storage/innobase/btr/btr0sea.c: Auto merged storage/innobase/buf/buf0buf.c: Auto merged storage/innobase/buf/buf0flu.c: Auto merged storage/innobase/buf/buf0lru.c: Auto merged storage/innobase/buf/buf0rea.c: Auto merged storage/innobase/data/data0data.c: Auto merged storage/innobase/data/data0type.c: Auto merged storage/innobase/dict/dict0boot.c: Auto merged storage/innobase/dict/dict0crea.c: Auto merged storage/innobase/dict/dict0dict.c: Auto merged storage/innobase/dict/dict0mem.c: Auto merged storage/innobase/fil/fil0fil.c: Auto merged storage/innobase/fsp/fsp0fsp.c: Auto merged storage/innobase/ibuf/ibuf0ibuf.c: Auto merged storage/innobase/include/btr0btr.h: Auto merged storage/innobase/include/btr0btr.ic: Auto merged storage/innobase/include/btr0cur.h: Auto merged storage/innobase/include/btr0cur.ic: Auto merged storage/innobase/include/buf0buf.h: Auto merged storage/innobase/include/buf0buf.ic: Auto merged storage/innobase/include/buf0lru.h: Auto merged storage/innobase/include/data0type.h: Auto merged storage/innobase/include/data0type.ic: Auto merged storage/innobase/include/dyn0dyn.h: Auto merged storage/innobase/include/dyn0dyn.ic: Auto merged storage/innobase/include/lock0lock.h: Auto merged storage/innobase/include/log0log.h: Auto merged storage/innobase/include/mach0data.h: Auto merged storage/innobase/include/mach0data.ic: Auto merged storage/innobase/include/mem0mem.ic: Auto merged storage/innobase/include/mtr0log.h: Auto merged storage/innobase/include/mtr0mtr.h: Auto merged storage/innobase/include/os0file.h: Auto merged storage/innobase/include/page0cur.h: Auto merged storage/innobase/include/page0cur.ic: Auto merged storage/innobase/include/page0page.h: Auto merged storage/innobase/include/page0page.ic: Auto merged storage/innobase/include/read0read.ic: Auto merged storage/innobase/include/rem0rec.h: Auto merged storage/innobase/include/rem0rec.ic: Auto merged storage/innobase/include/row0mysql.h: Auto merged storage/innobase/include/row0sel.ic: Auto merged storage/innobase/include/row0upd.ic: Auto merged storage/innobase/include/sync0rw.ic: Auto merged storage/innobase/include/trx0rseg.ic: Auto merged storage/innobase/include/trx0trx.h: Auto merged storage/innobase/include/univ.i: Auto merged storage/innobase/include/ut0dbg.h: Auto merged storage/innobase/include/ut0rnd.ic: Auto merged storage/innobase/lock/lock0lock.c: Auto merged storage/innobase/log/log0log.c: Auto merged storage/innobase/log/log0recv.c: Auto merged storage/innobase/mtr/mtr0log.c: Auto merged storage/innobase/mtr/mtr0mtr.c: Auto merged storage/innobase/os/os0file.c: Auto merged storage/innobase/page/page0cur.c: Auto merged storage/innobase/page/page0page.c: Auto merged storage/innobase/rem/rem0cmp.c: Auto merged storage/innobase/rem/rem0rec.c: Auto merged storage/innobase/row/row0ins.c: Auto merged storage/innobase/row/row0mysql.c: Auto merged storage/innobase/row/row0purge.c: Auto merged storage/innobase/row/row0row.c: Auto merged storage/innobase/row/row0sel.c: Auto merged storage/innobase/row/row0undo.c: Auto merged storage/innobase/row/row0upd.c: Auto merged storage/innobase/row/row0vers.c: Auto merged storage/innobase/srv/srv0start.c: Auto merged storage/innobase/sync/sync0sync.c: Auto merged storage/innobase/trx/trx0rec.c: Auto merged storage/innobase/trx/trx0roll.c: Auto merged storage/innobase/trx/trx0trx.c: Auto merged storage/innobase/ut/ut0dbg.c: Auto merged
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/btr/btr0btr.c174
-rw-r--r--storage/innobase/btr/btr0cur.c251
-rw-r--r--storage/innobase/btr/btr0pcur.c66
-rw-r--r--storage/innobase/btr/btr0sea.c191
-rw-r--r--storage/innobase/buf/buf0buf.c36
-rw-r--r--storage/innobase/buf/buf0flu.c6
-rw-r--r--storage/innobase/buf/buf0lru.c6
-rw-r--r--storage/innobase/buf/buf0rea.c8
-rw-r--r--storage/innobase/data/data0data.c2
-rw-r--r--storage/innobase/data/data0type.c4
-rw-r--r--storage/innobase/dict/dict0boot.c9
-rw-r--r--storage/innobase/dict/dict0crea.c2
-rw-r--r--storage/innobase/dict/dict0dict.c23
-rw-r--r--storage/innobase/dict/dict0mem.c1
-rw-r--r--storage/innobase/fil/fil0fil.c3
-rw-r--r--storage/innobase/fsp/fsp0fsp.c4
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c54
-rw-r--r--storage/innobase/include/btr0btr.h11
-rw-r--r--storage/innobase/include/btr0btr.ic4
-rw-r--r--storage/innobase/include/btr0cur.h2
-rw-r--r--storage/innobase/include/btr0cur.ic4
-rw-r--r--storage/innobase/include/buf0buf.h20
-rw-r--r--storage/innobase/include/buf0buf.ic29
-rw-r--r--storage/innobase/include/buf0lru.h2
-rw-r--r--storage/innobase/include/data0type.h2
-rw-r--r--storage/innobase/include/data0type.ic4
-rw-r--r--storage/innobase/include/dyn0dyn.h2
-rw-r--r--storage/innobase/include/dyn0dyn.ic7
-rw-r--r--storage/innobase/include/lock0lock.h19
-rw-r--r--storage/innobase/include/log0log.h4
-rw-r--r--storage/innobase/include/mach0data.h21
-rw-r--r--storage/innobase/include/mach0data.ic31
-rw-r--r--storage/innobase/include/mem0mem.ic2
-rw-r--r--storage/innobase/include/mtr0log.h14
-rw-r--r--storage/innobase/include/mtr0mtr.h6
-rw-r--r--storage/innobase/include/os0file.h13
-rw-r--r--storage/innobase/include/page0cur.h8
-rw-r--r--storage/innobase/include/page0cur.ic22
-rw-r--r--storage/innobase/include/page0page.h68
-rw-r--r--storage/innobase/include/page0page.ic270
-rw-r--r--storage/innobase/include/read0read.ic9
-rw-r--r--storage/innobase/include/rem0rec.h57
-rw-r--r--storage/innobase/include/rem0rec.ic120
-rw-r--r--storage/innobase/include/row0mysql.h17
-rw-r--r--storage/innobase/include/row0sel.ic2
-rw-r--r--storage/innobase/include/row0upd.ic2
-rw-r--r--storage/innobase/include/sync0rw.ic39
-rw-r--r--storage/innobase/include/trx0rseg.ic4
-rw-r--r--storage/innobase/include/trx0trx.h20
-rw-r--r--storage/innobase/include/univ.i26
-rw-r--r--storage/innobase/include/ut0dbg.h119
-rw-r--r--storage/innobase/include/ut0rnd.ic6
-rw-r--r--storage/innobase/lock/lock0lock.c344
-rw-r--r--storage/innobase/log/log0log.c62
-rw-r--r--storage/innobase/log/log0recv.c55
-rw-r--r--storage/innobase/mtr/mtr0log.c24
-rw-r--r--storage/innobase/mtr/mtr0mtr.c12
-rw-r--r--storage/innobase/os/os0file.c30
-rw-r--r--storage/innobase/page/page0cur.c56
-rw-r--r--storage/innobase/page/page0page.c147
-rw-r--r--storage/innobase/rem/rem0cmp.c99
-rw-r--r--storage/innobase/rem/rem0rec.c145
-rw-r--r--storage/innobase/row/row0ins.c108
-rw-r--r--storage/innobase/row/row0mysql.c55
-rw-r--r--storage/innobase/row/row0purge.c4
-rw-r--r--storage/innobase/row/row0row.c10
-rw-r--r--storage/innobase/row/row0sel.c373
-rw-r--r--storage/innobase/row/row0undo.c2
-rw-r--r--storage/innobase/row/row0upd.c27
-rw-r--r--storage/innobase/row/row0vers.c18
-rw-r--r--storage/innobase/srv/srv0start.c5
-rw-r--r--storage/innobase/sync/sync0sync.c4
-rw-r--r--storage/innobase/trx/trx0rec.c4
-rw-r--r--storage/innobase/trx/trx0roll.c2
-rw-r--r--storage/innobase/trx/trx0trx.c10
-rw-r--r--storage/innobase/ut/ut0dbg.c65
76 files changed, 1812 insertions, 1675 deletions
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index 1744fc36f4d..2d84586216a 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -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)) {
+
+ rec_t* next_rec;
+
+ next_rec = page_rec_get_next(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) {
+ 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);
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index e093c911f22..98d90ecf18a 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -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 (!page) {
- mem_heap_free(heap);
+ if (!ptr || !page) {
- return(ptr);
+ goto func_exit;
}
-
+
+ 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++) {
diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c
index 74feff8653c..cb398b4afab 100644
--- a/storage/innobase/btr/btr0pcur.c
+++ b/storage/innobase/btr/btr0pcur.c
@@ -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;
- cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
- cursor->old_stored = BTR_PCUR_OLD_STORED;
+ if (page_rec_is_supremum_low(offs)) {
- return;
+ cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
+ } 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);
diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
index 97fdce2df75..f705fee4275 100644
--- a/storage/innobase/btr/btr0sea.c
+++ b/storage/innobase/btr/btr0sea.c
@@ -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);
}
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 89f851709db..78189617aab 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -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. */
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index 592ed972376..ffb16790b2d 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -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;
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index 18c4f8c10fb..a0157da2d42 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -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 */
diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
index d9dc2ca93f5..813ca589907 100644
--- a/storage/innobase/buf/buf0rea.c
+++ b/storage/innobase/buf/buf0rea.c
@@ -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 */
}
diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c
index 5f74dde8710..194213a04e1 100644
--- a/storage/innobase/data/data0data.c
+++ b/storage/innobase/data/data0data.c
@@ -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);
diff --git a/storage/innobase/data/data0type.c b/storage/innobase/data/data0type.c
index 3fcd666b5a5..d4264ad2926 100644
--- a/storage/innobase/data/data0type.c
+++ b/storage/innobase/data/data0type.c
@@ -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));
diff --git a/storage/innobase/dict/dict0boot.c b/storage/innobase/dict/dict0boot.c
index 0f6d55c9341..18a707a1b93 100644
--- a/storage/innobase/dict/dict0boot.c
+++ b/storage/innobase/dict/dict0boot.c
@@ -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);
diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c
index 1f12386e413..c7d6ffd2c22 100644
--- a/storage/innobase/dict/dict0crea.c
+++ b/storage/innobase/dict/dict0crea.c
@@ -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
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 0c39defeada..9580a80e7e7 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -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 */
}
/**************************************************************************
diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c
index 48b9f28d292..eec35310039 100644
--- a/storage/innobase/dict/dict0mem.c
+++ b/storage/innobase/dict/dict0mem.c
@@ -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);
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 8600f583dbd..299b55f3d2b 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -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);
}
diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
index ef8e70646c6..ad4228f6797 100644
--- a/storage/innobase/fsp/fsp0fsp.c
+++ b/storage/innobase/fsp/fsp0fsp.c
@@ -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);
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 5ad61e2590f..712d43f916c 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -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);
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index 0b19e64d4e0..1f3a32fa70c 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -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
diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
index 1d1f97d3668..a0860b1c3a7 100644
--- a/storage/innobase/include/btr0btr.ic
+++ b/storage/innobase/include/btr0btr.ic
@@ -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));
}
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 0a8d8ceaeb7..352d1739b6a 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -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. */
diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic
index dcad3e9e14d..bf8a6efb68d 100644
--- a/storage/innobase/include/btr0cur.ic
+++ b/storage/innobase/include/btr0cur.ic
@@ -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);
}
/*************************************************************
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 5ee323f1b1e..ae8d0411c12 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -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
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index 681a0ef000a..d949254d47d 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -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));
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 45164dd561e..fb29b44ba98 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -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"
diff --git a/storage/innobase/include/data0type.h b/storage/innobase/include/data0type.h
index a4d2c1a2e1d..7e9692eca5a 100644
--- a/storage/innobase/include/data0type.h
+++ b/storage/innobase/include/data0type.h
@@ -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;
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index a87a08ca582..06d45dd5501 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -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: "
diff --git a/storage/innobase/include/dyn0dyn.h b/storage/innobase/include/dyn0dyn.h
index abee62300e3..1df976a5301 100644
--- a/storage/innobase/include/dyn0dyn.h
+++ b/storage/innobase/include/dyn0dyn.h
@@ -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 */
/*#################################################################*/
diff --git a/storage/innobase/include/dyn0dyn.ic b/storage/innobase/include/dyn0dyn.ic
index b6c4808398b..c1b8f2cb8ce 100644
--- a/storage/innobase/include/dyn0dyn.ic
+++ b/storage/innobase/include/dyn0dyn.ic
@@ -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;
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 45a81a4ac77..20b1f1d7145 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -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 */
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index d14a116072d..7f3f10438b4 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -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
diff --git a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h
index 7ad760cd60f..f9a3ff521d5 100644
--- a/storage/innobase/include/mach0data.h
+++ b/storage/innobase/include/mach0data.h
@@ -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. */
diff --git a/storage/innobase/include/mach0data.ic b/storage/innobase/include/mach0data.ic
index 3ffb9baa344..888f3f743e4 100644
--- a/storage/innobase/include/mach0data.ic
+++ b/storage/innobase/include/mach0data.ic
@@ -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. */
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 82d88099c3f..8c87c884d78 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -623,7 +623,7 @@ mem_strdupq(
}
*d++ = q;
*d++ = '\0';
- ut_ad(len == d - dst);
+ ut_ad((ssize_t) len == d - dst);
return(dst);
}
diff --git a/storage/innobase/include/mtr0log.h b/storage/innobase/include/mtr0log.h
index c0636ea1e1e..6a3920aa8a1 100644
--- a/storage/innobase/include/mtr0log.h
+++ b/storage/innobase/include/mtr0log.h
@@ -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
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 071279d5259..f44e813cf6b 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -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
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index f55c345537e..e75281dd93c 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -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 */
diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h
index 4fc62f37db7..e89e740e775 100644
--- a/storage/innobase/include/page0cur.h
+++ b/storage/innobase/include/page0cur.h
@@ -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
diff --git a/storage/innobase/include/page0cur.ic b/storage/innobase/include/page0cur.ic
index e99d799b372..f8346819e84 100644
--- a/storage/innobase/include/page0cur.ic
+++ b/storage/innobase/include/page0cur.ic
@@ -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));
}
/**************************************************************
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 144c297b811..c4ffa39d3ac 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -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,47 +415,55 @@ 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(
-/*=================*/
+page_rec_is_user_rec_low(
+/*=====================*/
/* out: TRUE if a user record */
- rec_t* rec); /* in: 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(
-/*=================*/
+page_rec_is_supremum_low(
+/*=====================*/
/* out: TRUE if the supremum record */
- rec_t* rec); /* in: 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(
-/*================*/
+page_rec_is_infimum_low(
+/*=====================*/
/* out: TRUE if the infimum record */
- rec_t* rec); /* in: record */
+ ulint offset);/* in: record offset on page */
+
/****************************************************************
-TRUE if the record is the first user record on the page. */
+TRUE if the record is a 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 */
+page_rec_is_user_rec(
+/*=================*/
+ /* out: TRUE if a user record */
+ const rec_t* rec); /* in: record */
/****************************************************************
-TRUE if the record is the last user record on the page. */
+TRUE if the record is the supremum record on a page. */
UNIV_INLINE
ibool
-page_rec_is_last_user_rec(
-/*======================*/
- /* out: TRUE if last user record */
- rec_t* rec); /* in: record */
+page_rec_is_supremum(
+/*=================*/
+ /* 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 */
+ 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 */
/****************************************************************
diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
index bc0805ca30c..fd5281fdbec 100644
--- a/storage/innobase/include/page0page.ic
+++ b/storage/innobase/include/page0page.ic
@@ -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(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_header_get_field(page, PAGE_N_HEAP) & 0x8000));
+ return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE)));
}
/****************************************************************
@@ -205,112 +218,107 @@ page_get_supremum_rec(
TRUE if the record is a user record on the page. */
UNIV_INLINE
ibool
-page_rec_is_user_rec(
-/*=================*/
+page_rec_is_user_rec_low(
+/*=====================*/
/* out: TRUE if a user record */
- rec_t* rec) /* in: record */
+ ulint offset) /* in: record offset on page */
{
- 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);
- }
+ 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(TRUE);
+ 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(
-/*=================*/
+page_rec_is_supremum_low(
+/*=====================*/
/* out: TRUE if the supremum record */
- rec_t* rec) /* in: record */
+ ulint offset) /* in: record offset on page */
{
- ut_ad(rec);
+ ut_ad(offset >= PAGE_NEW_INFIMUM);
+ ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
- if (rec == page_get_supremum_rec(buf_frame_align(rec))) {
-
- return(TRUE);
- }
-
- return(FALSE);
+ 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(
-/*================*/
+page_rec_is_infimum_low(
+/*=====================*/
/* out: TRUE if the infimum record */
- rec_t* rec) /* in: record */
+ ulint offset) /* in: record offset on page */
{
- ut_ad(rec);
-
- if (rec == page_get_infimum_rec(buf_frame_align(rec))) {
-
- return(TRUE);
- }
+ ut_ad(offset >= PAGE_NEW_INFIMUM);
+ ut_ad(offset <= UNIV_PAGE_SIZE - PAGE_EMPTY_DIR_START);
- return(FALSE);
+ return(UNIV_UNLIKELY(offset == PAGE_NEW_INFIMUM)
+ || UNIV_UNLIKELY(offset == PAGE_OLD_INFIMUM));
}
/****************************************************************
-TRUE if the record is the first user record on the page. */
+TRUE if the record is a 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 */
+page_rec_is_user_rec(
+/*=================*/
+ /* 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_rec_get_next(
- page_get_infimum_rec(buf_frame_align(rec)))) {
-
- return(TRUE);
- }
-
- return(FALSE);
+ return(page_rec_is_user_rec_low(
+ ut_align_offset(rec, UNIV_PAGE_SIZE)));
}
/****************************************************************
-TRUE if the record is the last user record on the page. */
+TRUE if the record is the supremum record on a page. */
UNIV_INLINE
ibool
-page_rec_is_last_user_rec(
-/*======================*/
- /* out: TRUE if last user record */
- rec_t* rec) /* in: record */
+page_rec_is_supremum(
+/*=================*/
+ /* 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(FALSE);
- }
-
- if (page_rec_get_next(rec)
- == page_get_supremum_rec(buf_frame_align(rec))) {
-
- return(TRUE);
- }
+ return(page_rec_is_supremum_low(
+ ut_align_offset(rec, UNIV_PAGE_SIZE)));
+}
- return(FALSE);
+/****************************************************************
+TRUE if the record is the infimum record on a page. */
+UNIV_INLINE
+ibool
+page_rec_is_infimum(
+/*================*/
+ /* out: TRUE if the infimum record */
+ const rec_t* rec) /* in: record */
+{
+ 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) {
- fprintf(stderr,
-"InnoDB: Next record offset is nonsensical %lu in record at offset %lu\n",
- (ulong)offs, (ulong)(rec - page));
+ if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) {
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);
+ 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);
- occupied = page_header_get_field(page, PAGE_HEAP_TOP)
- - (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END)
- + page_dir_calc_reserved_space(
+ 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(comp);
-
+ 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);
diff --git a/storage/innobase/include/read0read.ic b/storage/innobase/include/read0read.ic
index 03d84ee0c51..ec9ef5814bb 100644
--- a/storage/innobase/include/read0read.ic
+++ b/storage/innobase/include/read0read.ic
@@ -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);
}
}
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 134c37c8030..c068f4cb73c 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -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 */
/**********************************************************
diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic
index 2593fb8edeb..d60fb3b9eda 100644
--- a/storage/innobase/include/rem0rec.ic
+++ b/storage/innobase/include/rem0rec.ic
@@ -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;
-
- ut_ad(TRUE == 1);
- ut_ad(flag <= TRUE);
+ ulint val;
- 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);
}
/**********************************************************
@@ -633,26 +632,6 @@ rec_get_node_ptr_flag(
}
/**********************************************************
-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. */
UNIV_INLINE
@@ -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. */
-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. */
+Returns nonzero 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));
}
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index e44d689b88b..4bb9fa63cd1 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -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
diff --git a/storage/innobase/include/row0sel.ic b/storage/innobase/include/row0sel.ic
index 595cea1138b..600c6204571 100644
--- a/storage/innobase/include/row0sel.ic
+++ b/storage/innobase/include/row0sel.ic
@@ -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);
diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
index e2d81a39cfa..acbb11aa1c7 100644
--- a/storage/innobase/include/row0upd.ic
+++ b/storage/innobase/include/row0upd.ic
@@ -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);
diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic
index 3a92100ba01..b1ae636010a 100644
--- a/storage/innobase/include/sync0rw.ic
+++ b/storage/innobase/include/sync0rw.ic
@@ -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);
}
diff --git a/storage/innobase/include/trx0rseg.ic b/storage/innobase/include/trx0rseg.ic
index 35e927f5e79..c9ac50ebf16 100644
--- a/storage/innobase/include/trx0rseg.ic
+++ b/storage/innobase/include/trx0rseg.ic
@@ -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;
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index d46613c3a68..8df50d6703d 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -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)
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 8158c198e21..132ac9e18c5 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -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"
diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h
index 5f30a894874..bc3f852626a 100644
--- a/storage/innobase/include/ut0dbg.h
+++ b/storage/innobase/include/ut0dbg.h
@@ -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)
diff --git a/storage/innobase/include/ut0rnd.ic b/storage/innobase/include/ut0rnd.ic
index 06d7012f60b..d2ab087d491 100644
--- a/storage/innobase/include/ut0rnd.ic
+++ b/storage/innobase/include/ut0rnd.ic
@@ -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++;
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 73ecc717e0e..48db7ced0cb 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -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);
}
}
diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c
index 560f51401ac..5953262ece7 100644
--- a/storage/innobase/log/log0log.c
+++ b/storage/innobase/log/log0log.c
@@ -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 */
}
}
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index 6597122f104..0417d01d89a 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -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,
diff --git a/storage/innobase/mtr/mtr0log.c b/storage/innobase/mtr/mtr0log.c
index 4f826f242e8..0308619073a 100644
--- a/storage/innobase/mtr/mtr0log.c
+++ b/storage/innobase/mtr/mtr0log.c
@@ -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);
diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c
index 6e918806eb1..da045be1f62 100644
--- a/storage/innobase/mtr/mtr0mtr.c
+++ b/storage/innobase/mtr/mtr0mtr.c
@@ -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;
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index ac5d1c72c72..8102f24f25a 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -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 */
diff --git a/storage/innobase/page/page0cur.c b/storage/innobase/page/page0cur.c
index 7738f5a34f0..df6d898d4ac 100644
--- a/storage/innobase/page/page0cur.c
+++ b/storage/innobase/page/page0cur.c
@@ -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));
diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
index f3217e91f58..9c957ac8554 100644
--- a/storage/innobase/page/page0page.c
+++ b/storage/innobase/page/page0page.c
@@ -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);
-
- while (rec_get_n_owned(rec, comp) == 0) {
- steps++;
- rec = page_rec_get_next(rec);
+ first_slot = page_dir_get_nth_slot(page, 0);
+ slot = page_dir_get_nth_slot(page, page_dir_get_n_slots(page) - 1);
+
+ 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) {
+ if (page_is_comp(page)) {
fputs("(compact record)", stderr);
} else {
- rec_print_old(stderr, original_rec);
+ rec_print_old(stderr, rec);
}
- fprintf(stderr, "\n"
- "InnoDB: on that page. Steps %lu.\n", (ulong) steps);
- fputs(
+ fputs("\n"
+ "InnoDB: on that page.\n"
"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);
+ 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);
}
diff --git a/storage/innobase/rem/rem0cmp.c b/storage/innobase/rem/rem0cmp.c
index 74348b865a8..7c33476fb9e 100644
--- a/storage/innobase/rem/rem0cmp.c
+++ b/storage/innobase/rem/rem0cmp.c
@@ -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;
}
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index 542c746209b..580a7bfe509 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -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);
}
}
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 303fe5749bc..776094d0de5 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -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);
-
- /* TODO: pad in UCS-2 with 0x0020.
- TODO: How does the special truncation of
- UTF-8 CHAR cols affect this? */
+ min_size = dtype_get_min_size(type);
- 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,15 +1943,20 @@ 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))));
+ }
+
+#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 (!page_rec_is_supremum(first_rec)) {
- ut_a(rec_get_n_fields(first_rec, index)
+ 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);
@@ -2048,7 +2064,7 @@ function_exit:
mtr_commit(&mtr);
}
- if (heap) {
+ if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index fafbef4c999..eb50b83a4d5 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -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;
@@ -971,25 +971,6 @@ run_again:
}
/*************************************************************************
-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. */
int
@@ -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); */
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index 5893e016011..abcf97110d9 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -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);
}
diff --git a/storage/innobase/row/row0row.c b/storage/innobase/row/row0row.c
index a6d3f1d5ab0..9a74397dc08 100644
--- a/storage/innobase/row/row0row.c
+++ b/storage/innobase/row/row0row.c
@@ -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);
}
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index 94cf82d6a3d..c7a548fe448 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -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);
diff --git a/storage/innobase/row/row0undo.c b/storage/innobase/row/row0undo.c
index abe73cbe705..435c0279dbb 100644
--- a/storage/innobase/row/row0undo.c
+++ b/storage/innobase/row/row0undo.c
@@ -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);
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 3305724a89b..cf2b8db5d32 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -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);
diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c
index 36f6c27636d..8e747423047 100644
--- a/storage/innobase/row/row0vers.c
+++ b/storage/innobase/row/row0vers.c
@@ -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);
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index 541b73b831d..7798e0c8e32 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -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++) {
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index e604912e996..f0f0e9a3a2e 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -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;
}
diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c
index fcb7582ce73..3f3cfd3b000 100644
--- a/storage/innobase/trx/trx0rec.c
+++ b/storage/innobase/trx/trx0rec.c
@@ -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);
diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c
index 69f7a99187f..fdfb7428129 100644
--- a/storage/innobase/trx/trx0roll.c
+++ b/storage/innobase/trx/trx0roll.c
@@ -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);
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index c6d1f953772..9e155ee1de0 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -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) {
diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c
index 0f6a27d35d9..e810d8dead7 100644
--- a/storage/innobase/ut/ut0dbg.c
+++ b/storage/innobase/ut/ut0dbg.c
@@ -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__ */
+
+/*****************************************************************
+Report a failed assertion. */
-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 =
+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;
+}
+
+#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. */
-const char* ut_dbg_msg_stop =
-"InnoDB: Thread %lu stopped in file %s line %lu\n";
+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__ */