Commit efb74613 authored by marko's avatar marko

branches/zip: btr_cur_optimistic_insert(): Set the insert buffer free bits

exactly.  Rename the local variable "ulint level" to "ibool leaf".
Document that if the function returns DB_SUCCESS on a compressed page that
is covered by the insert buffer, the mini-transaction must be committed
before latching any further pages.  Verify that this is the case on all
execution paths.
parent 382cb9fd
...@@ -1043,7 +1043,11 @@ btr_cur_optimistic_insert( ...@@ -1043,7 +1043,11 @@ btr_cur_optimistic_insert(
const ulint* ext, /* in: array of extern field numbers */ const ulint* ext, /* in: array of extern field numbers */
ulint n_ext, /* in: number of elements in vec */ ulint n_ext, /* in: number of elements in vec */
que_thr_t* thr, /* in: query thread or NULL */ que_thr_t* thr, /* in: query thread or NULL */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr; if this function returns
DB_SUCCESS on a leaf page of a secondary
index in a compressed tablespace, the
mtr must be committed before latching
any further pages */
{ {
big_rec_t* big_rec_vec = NULL; big_rec_t* big_rec_vec = NULL;
dict_index_t* index; dict_index_t* index;
...@@ -1051,8 +1055,9 @@ btr_cur_optimistic_insert( ...@@ -1051,8 +1055,9 @@ btr_cur_optimistic_insert(
buf_block_t* block; buf_block_t* block;
page_t* page; page_t* page;
ulint max_size; ulint max_size;
ulint max_size_zip = 0;
rec_t* dummy_rec; rec_t* dummy_rec;
ulint level; ibool leaf;
ibool reorg; ibool reorg;
ibool inherit; ibool inherit;
ulint zip_size; ulint zip_size;
...@@ -1080,7 +1085,18 @@ btr_cur_optimistic_insert( ...@@ -1080,7 +1085,18 @@ btr_cur_optimistic_insert(
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
max_size = page_get_max_insert_size_after_reorganize(page, 1); max_size = page_get_max_insert_size_after_reorganize(page, 1);
level = btr_page_get_level(page, mtr); leaf = page_is_leaf(page);
/* If necessary for updating the insert buffer bitmap,
calculate the current maximum insert size on a compressed page. */
if (zip_size && UNIV_LIKELY(leaf) && !dict_index_is_clust(index)) {
lint zip_max = page_zip_max_ins_size(
buf_block_get_page_zip(block), FALSE);
if (zip_max >= 0 && max_size > (ulint) zip_max) {
max_size_zip = (ulint) zip_max;
}
}
/* Calculate the record size when entry is converted to a record */ /* Calculate the record size when entry is converted to a record */
rec_size = rec_get_converted_size(index, entry, ext, n_ext); rec_size = rec_get_converted_size(index, entry, ext, n_ext);
...@@ -1106,7 +1122,7 @@ btr_cur_optimistic_insert( ...@@ -1106,7 +1122,7 @@ btr_cur_optimistic_insert(
if (dict_index_is_clust(index) if (dict_index_is_clust(index)
&& (page_get_n_recs(page) >= 2) && (page_get_n_recs(page) >= 2)
&& UNIV_LIKELY(0 == level) && UNIV_LIKELY(leaf)
&& (dict_index_get_space_reserve() + rec_size > max_size) && (dict_index_get_space_reserve() + rec_size > max_size)
&& (btr_page_get_split_rec_to_right(cursor, &dummy_rec) && (btr_page_get_split_rec_to_right(cursor, &dummy_rec)
|| btr_page_get_split_rec_to_left(cursor, &dummy_rec))) { || btr_page_get_split_rec_to_left(cursor, &dummy_rec))) {
...@@ -1196,7 +1212,7 @@ fail_err: ...@@ -1196,7 +1212,7 @@ fail_err:
} }
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
if (!reorg && (0 == level) && (cursor->flag == BTR_CUR_HASH)) { if (!reorg && leaf && (cursor->flag == BTR_CUR_HASH)) {
btr_search_update_hash_node_on_insert(cursor); btr_search_update_hash_node_on_insert(cursor);
} else { } else {
btr_search_update_hash_on_insert(cursor); btr_search_update_hash_on_insert(cursor);
...@@ -1214,17 +1230,9 @@ fail_err: ...@@ -1214,17 +1230,9 @@ fail_err:
buf_block_get_page_no(block), max_size, buf_block_get_page_no(block), max_size,
rec_size + PAGE_DIR_SLOT_SIZE, index->type); rec_size + PAGE_DIR_SLOT_SIZE, index->type);
#endif #endif
if (!dict_index_is_clust(index) && UNIV_LIKELY(0 == level)) { if (!dict_index_is_clust(index) && leaf) {
/* Update the free bits of the B-tree page in the /* Update the free bits of the B-tree page in the
insert buffer bitmap. This has to be done in a insert buffer bitmap. */
separate mini-transaction that is committed before the
main mini-transaction. Since insert buffer bitmap
pages have a lower rank than B-tree pages, we must not
access other pages in the same mini-transaction after
accessing an insert buffer bitmap page. Because the
mini-transaction where this function is invoked may
access other pages, we must update the insert
buffer bitmap in a separate mini-transaction. */
/* The free bits in the insert buffer bitmap must /* The free bits in the insert buffer bitmap must
never exceed the free space on a page. It is safe to never exceed the free space on a page. It is safe to
...@@ -1237,13 +1245,12 @@ fail_err: ...@@ -1237,13 +1245,12 @@ fail_err:
the free bits could momentarily be set too high. */ the free bits could momentarily be set too high. */
if (zip_size) { if (zip_size) {
/* Because the free bits may be incremented /* Update the bits in the same mini-transaction. */
and we cannot update the insert buffer bitmap ibuf_update_free_bits_low(zip_size, block,
in the same mini-transaction, the only safe max_size_zip, mtr);
thing we can do here is the pessimistic
approach: reset the free bits. */
ibuf_reset_free_bits(block);
} else { } else {
/* Decrement the bits in a separate
mini-transaction. */
ibuf_update_free_bits_if_full( ibuf_update_free_bits_if_full(
block, max_size, block, max_size,
rec_size + PAGE_DIR_SLOT_SIZE); rec_size + PAGE_DIR_SLOT_SIZE);
......
...@@ -180,7 +180,11 @@ btr_cur_optimistic_insert( ...@@ -180,7 +180,11 @@ btr_cur_optimistic_insert(
const ulint* ext, /* in: array of extern field numbers */ const ulint* ext, /* in: array of extern field numbers */
ulint n_ext, /* in: number of elements in vec */ ulint n_ext, /* in: number of elements in vec */
que_thr_t* thr, /* in: query thread or NULL */ que_thr_t* thr, /* in: query thread or NULL */
mtr_t* mtr); /* in: mtr */ mtr_t* mtr); /* in: mtr; if this function returns
DB_SUCCESS on a leaf page of a secondary
index in a compressed tablespace, the
mtr must be committed before latching
any further pages */
/***************************************************************** /*****************************************************************
Performs an insert on a page of an index tree. It is assumed that mtr Performs an insert on a page of an index tree. It is assumed that mtr
holds an x-latch on the tree and on the cursor page. If the insert is holds an x-latch on the tree and on the cursor page. If the insert is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment