diff options
author | Marko Mäkelä <marko.makela@oracle.com> | 2011-10-12 09:00:49 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@oracle.com> | 2011-10-12 09:00:49 +0300 |
commit | 6d59064948fa916667a7cc885ecdc4df3b8fb871 (patch) | |
tree | 1ef0f83c0171c603f5016d3111b4f4333b8f6a17 | |
parent | 73db2a1504188611c3348e1bd55d181aea6ab533 (diff) | |
download | mariadb-git-6d59064948fa916667a7cc885ecdc4df3b8fb871.tar.gz |
Bug#13006367 62487: innodb takes 3 minutes to clean up the adaptive
hash index at shutdown
btr_search_disable(): Just drop the entire adaptive hash index,
without dropping every record separately.
buf_pool_clear_hash_index(): Renamed and simplified from
buf_pool_drop_hash_index(). Set block->index = NULL for every block in
the buffer pool. Do not release the btr_search_latch. The caller will
have to adjust other data structures.
Remove block->is_hashed. It is redundant, should be always equal to
block->index != NULL.
Remove btr_search_fully_disabled, btr_search_enabled_mutex, and
SYNC_SEARCH_SYS_CONF. We drop the AHI in one pass, without releasing
the btr_search_latch in between.
Replace void* with const rec_t* and add assertions on btr_search_latch
and btr_search_enabled to ha0ha.h, ha0ha.ic, ha0ha.c.
page_set_max_trx_id(): Ignore the adaptive hash index. I forgot to
push this in rb:750.
btr0sea.c: Always after acquiring btr_search_latch, check for
block->index==NULL or !btr_search_enabled. We can now set
block->index=NULL while only holding btr_search_latch in exclusive
mode. Always acquire btr_search_latch before reading block->index,
except in shortcuts when testing for block->index == NULL.
ha_clear(), ha_search(): Unused function, remove.
buf_page_peek_if_search_hashed(): Remove. This function may avoid
latching a page at the cost of doing a duplicate buf_pool->page_hash
lookup.
rb:775 approved by Inaam Rana
-rw-r--r-- | storage/innodb_plugin/ChangeLog | 10 | ||||
-rw-r--r-- | storage/innodb_plugin/btr/btr0cur.c | 2 | ||||
-rw-r--r-- | storage/innodb_plugin/btr/btr0sea.c | 254 | ||||
-rw-r--r-- | storage/innodb_plugin/buf/buf0buf.c | 119 | ||||
-rw-r--r-- | storage/innodb_plugin/buf/buf0lru.c | 6 | ||||
-rw-r--r-- | storage/innodb_plugin/ha/ha0ha.c | 69 | ||||
-rw-r--r-- | storage/innodb_plugin/handler/ha_innodb.cc | 1 | ||||
-rw-r--r-- | storage/innodb_plugin/ibuf/ibuf0ibuf.c | 2 | ||||
-rw-r--r-- | storage/innodb_plugin/include/btr0sea.h | 34 | ||||
-rw-r--r-- | storage/innodb_plugin/include/btr0types.h | 25 | ||||
-rw-r--r-- | storage/innodb_plugin/include/buf0buf.h | 44 | ||||
-rw-r--r-- | storage/innodb_plugin/include/ha0ha.h | 23 | ||||
-rw-r--r-- | storage/innodb_plugin/include/ha0ha.ic | 54 | ||||
-rw-r--r-- | storage/innodb_plugin/include/row0upd.ic | 1 | ||||
-rw-r--r-- | storage/innodb_plugin/include/sync0sync.h | 1 | ||||
-rw-r--r-- | storage/innodb_plugin/page/page0page.c | 12 | ||||
-rw-r--r-- | storage/innodb_plugin/sync/sync0sync.c | 1 |
17 files changed, 272 insertions, 386 deletions
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index cdf8e8351a8..b560f69daea 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,13 @@ +2011-10-12 The InnoDB Team + + * btr/btr0cur.c, btr/btr0sea.c, buf/buf0buf.c, buf/buf0lru.c, + ha/ha0ha.c, handler/ha_innodb.cc, ibuf/ibuf0ibuf.c, include/btr0sea.h, + include/btr0types.h, include/buf0buf.h, include/ha0ha.h, + include/ha0ha.ic, include/row0upd.ic, include/sync0sync.h, + page/page0page.c, sync/sync0sync.c: + Fix Bug#13006367 62487: innodb takes 3 minutes to clean up + the adaptive hash index at shutdown + 2011-10-04 The InnoDB Team * include/sync0rw.h, sync/sync0rw.c: diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 4baa21d7c71..5fe16ff1215 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -1777,7 +1777,7 @@ btr_cur_update_in_place( was_delete_marked = rec_get_deleted_flag( rec, page_is_comp(buf_block_get_frame(block))); - is_hashed = block->is_hashed; + is_hashed = (block->index != NULL); if (is_hashed) { /* TO DO: Can we skip this if none of the fields diff --git a/storage/innodb_plugin/btr/btr0sea.c b/storage/innodb_plugin/btr/btr0sea.c index 88442b7d4f0..3dd30cbc0f3 100644 --- a/storage/innodb_plugin/btr/btr0sea.c +++ b/storage/innodb_plugin/btr/btr0sea.c @@ -44,12 +44,8 @@ Created 2/17/1996 Heikki Tuuri #include "ha0ha.h" /** Flag: has the search system been enabled? -Protected by btr_search_latch and btr_search_enabled_mutex. */ +Protected by btr_search_latch. */ UNIV_INTERN char btr_search_enabled = TRUE; -UNIV_INTERN ibool btr_search_fully_disabled = FALSE; - -/** Mutex protecting btr_search_enabled */ -static mutex_t btr_search_enabled_mutex; /** A dummy variable to fool the compiler */ UNIV_INTERN ulint btr_search_this_is_zero = 0; @@ -169,7 +165,6 @@ btr_search_sys_create( btr_search_latch_temp = mem_alloc(sizeof(rw_lock_t)); rw_lock_create(&btr_search_latch, SYNC_SEARCH_SYS); - mutex_create(&btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF); btr_search_sys = mem_alloc(sizeof(btr_search_sys_t)); @@ -199,27 +194,37 @@ void btr_search_disable(void) /*====================*/ { - mutex_enter(&btr_search_enabled_mutex); + dict_table_t* table; + + mutex_enter(&dict_sys->mutex); rw_lock_x_lock(&btr_search_latch); - /* Disable access to hash index, also tell ha_insert_for_fold() - stop adding new nodes to hash index, but still allow updating - existing nodes */ btr_search_enabled = FALSE; - /* Clear all block->is_hashed flags and remove all entries - from btr_search_sys->hash_index. */ - buf_pool_drop_hash_index(); + /* Clear the index->search_info->ref_count of every index in + the data dictionary cache. */ + for (table = UT_LIST_GET_FIRST(dict_sys->table_LRU); table; + table = UT_LIST_GET_NEXT(table_LRU, table)) { + + dict_index_t* index; + + for (index = dict_table_get_first_index(table); index; + index = dict_table_get_next_index(index)) { + + index->search_info->ref_count = 0; + } + } + + mutex_exit(&dict_sys->mutex); - /* hash index has been cleaned up, disallow any operation to - the hash index */ - btr_search_fully_disabled = TRUE; + /* Set all block->index = NULL. */ + buf_pool_clear_hash_index(); - /* btr_search_enabled_mutex should guarantee this. */ - ut_ad(!btr_search_enabled); + /* Clear the adaptive hash index. */ + hash_table_clear(btr_search_sys->hash_index); + mem_heap_empty(btr_search_sys->hash_index->heap); rw_lock_x_unlock(&btr_search_latch); - mutex_exit(&btr_search_enabled_mutex); } /********************************************************************//** @@ -229,14 +234,11 @@ void btr_search_enable(void) /*====================*/ { - mutex_enter(&btr_search_enabled_mutex); rw_lock_x_lock(&btr_search_latch); btr_search_enabled = TRUE; - btr_search_fully_disabled = FALSE; rw_lock_x_unlock(&btr_search_latch); - mutex_exit(&btr_search_enabled_mutex); } /*****************************************************************//** @@ -459,7 +461,7 @@ btr_search_update_block_hash_info( && (block->n_bytes == info->n_bytes) && (block->left_side == info->left_side)) { - if ((block->is_hashed) + if ((block->index) && (block->curr_n_fields == info->n_fields) && (block->curr_n_bytes == info->n_bytes) && (block->curr_left_side == info->left_side)) { @@ -488,7 +490,7 @@ btr_search_update_block_hash_info( / BTR_SEARCH_PAGE_BUILD_LIMIT) && (info->n_hash_potential >= BTR_SEARCH_BUILD_LIMIT)) { - if ((!block->is_hashed) + if ((!block->index) || (block->n_hash_helps > 2 * page_get_n_recs(block->frame)) || (block->n_fields != block->curr_n_fields) @@ -520,9 +522,9 @@ btr_search_update_hash_ref( buf_block_t* block, /*!< in: buffer block where cursor positioned */ btr_cur_t* cursor) /*!< in: cursor */ { - ulint fold; - rec_t* rec; - dulint index_id; + dict_index_t* index; + ulint fold; + const rec_t* rec; ut_ad(cursor->flag == BTR_CUR_HASH_FAIL); #ifdef UNIV_SYNC_DEBUG @@ -533,13 +535,15 @@ btr_search_update_hash_ref( ut_ad(page_align(btr_cur_get_rec(cursor)) == buf_block_get_frame(block)); - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); - ut_a(!dict_index_is_ibuf(cursor->index)); + ut_a(index == cursor->index); + ut_a(!dict_index_is_ibuf(index)); if ((info->n_hash_potential > 0) && (block->curr_n_fields == info->n_fields) @@ -556,12 +560,11 @@ btr_search_update_hash_ref( return; } - index_id = cursor->index->id; fold = rec_fold(rec, - rec_get_offsets(rec, cursor->index, offsets_, + rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), block->curr_n_fields, - block->curr_n_bytes, index_id); + block->curr_n_bytes, index->id); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -824,7 +827,7 @@ btr_search_guess_on_hash( mtr_t* mtr) /*!< in: mtr */ { buf_block_t* block; - rec_t* rec; + const rec_t* rec; ulint fold; dulint index_id; #ifdef notdefined @@ -910,7 +913,7 @@ btr_search_guess_on_hash( ut_ad(page_rec_is_user_rec(rec)); - btr_cur_position(index, rec, block, cursor); + btr_cur_position(index, (rec_t*) rec, block, cursor); /* Check the validity of the guess within the page */ @@ -1041,15 +1044,16 @@ btr_search_drop_page_hash_index( retry: rw_lock_s_lock(&btr_search_latch); - page = block->frame; + index = block->index; - if (UNIV_LIKELY(!block->is_hashed)) { + if (UNIV_LIKELY(!index)) { rw_lock_s_unlock(&btr_search_latch); return; } + ut_a(!dict_index_is_ibuf(index)); table = btr_search_sys->hash_index; #ifdef UNIV_SYNC_DEBUG @@ -1060,8 +1064,6 @@ retry: n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; - index = block->index; - ut_a(!dict_index_is_ibuf(index)); /* NOTE: The fields of block must not be accessed after releasing btr_search_latch, as the index page might only @@ -1071,6 +1073,7 @@ retry: ut_a(n_fields + n_bytes > 0); + page = block->frame; n_recs = page_get_n_recs(page); /* Calculate and cache fold values into an array for fast deletion @@ -1119,7 +1122,7 @@ next_rec: rw_lock_x_lock(&btr_search_latch); - if (UNIV_UNLIKELY(!block->is_hashed)) { + if (UNIV_UNLIKELY(!block->index)) { /* Someone else has meanwhile dropped the hash index */ goto cleanup; @@ -1147,9 +1150,8 @@ next_rec: ut_a(index->search_info->ref_count > 0); index->search_info->ref_count--; - block->is_hashed = FALSE; block->index = NULL; - + cleanup: #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG if (UNIV_UNLIKELY(block->n_pointers)) { @@ -1175,8 +1177,8 @@ cleanup: } /********************************************************************//** -Drops a page hash index when a page is freed from a fseg to the file system. -Drops possible hash index if the page happens to be in the buffer pool. */ +Drops a possible page hash index when a page is evicted from the buffer pool +or freed in a file segment. */ UNIV_INTERN void btr_search_drop_page_hash_when_freed( @@ -1189,28 +1191,19 @@ btr_search_drop_page_hash_when_freed( buf_block_t* block; mtr_t mtr; - if (!buf_page_peek_if_search_hashed(space, page_no)) { - - return; - } - mtr_start(&mtr); - /* We assume that if the caller has a latch on the page, then the - caller has already dropped the hash index for the page, and we never - get here. Therefore we can acquire the s-latch to the page without - having to fear a deadlock. */ + /* If the caller has a latch on the page, then the caller must + have a x-latch on the page and it must have already dropped + the hash index for the page. Because of the x-latch that we + are possibly holding, we cannot s-latch the page, but must + (recursively) x-latch it, even though we are only reading. */ - block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL, + block = buf_page_get_gen(space, zip_size, page_no, RW_X_LATCH, NULL, BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__, &mtr); - /* Because the buffer pool mutex was released by - buf_page_peek_if_search_hashed(), it is possible that the - block was removed from the buffer pool by another thread - before buf_page_get_gen() got a chance to acquire the buffer - pool mutex again. Thus, we must check for a NULL return. */ - if (UNIV_LIKELY(block != NULL)) { + if (block && block->index) { buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH); @@ -1242,7 +1235,6 @@ btr_search_build_page_hash_index( rec_t* next_rec; ulint fold; ulint next_fold; - dulint index_id; ulint n_cached; ulint n_recs; ulint* folds; @@ -1256,9 +1248,6 @@ btr_search_build_page_hash_index( ut_ad(index); ut_a(!dict_index_is_ibuf(index)); - table = btr_search_sys->hash_index; - page = buf_block_get_frame(block); - #ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX)); ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED) @@ -1267,9 +1256,17 @@ btr_search_build_page_hash_index( rw_lock_s_lock(&btr_search_latch); - if (block->is_hashed && ((block->curr_n_fields != n_fields) - || (block->curr_n_bytes != n_bytes) - || (block->curr_left_side != left_side))) { + if (!btr_search_enabled) { + rw_lock_s_unlock(&btr_search_latch); + return; + } + + table = btr_search_sys->hash_index; + page = buf_block_get_frame(block); + + if (block->index && ((block->curr_n_fields != n_fields) + || (block->curr_n_bytes != n_bytes) + || (block->curr_left_side != left_side))) { rw_lock_s_unlock(&btr_search_latch); @@ -1306,7 +1303,7 @@ btr_search_build_page_hash_index( n_cached = 0; - index_id = btr_page_get_index_id(page); + ut_a(UT_DULINT_EQ(index->id, btr_page_get_index_id(page))); rec = page_rec_get_next(page_get_infimum_rec(page)); @@ -1321,7 +1318,7 @@ btr_search_build_page_hash_index( } } - fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id); + fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id); if (left_side) { @@ -1348,7 +1345,7 @@ btr_search_build_page_hash_index( offsets = rec_get_offsets(next_rec, index, offsets, n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, - n_bytes, index_id); + n_bytes, index->id); if (fold != next_fold) { /* Insert an entry into the hash index */ @@ -1373,13 +1370,13 @@ btr_search_build_page_hash_index( rw_lock_x_lock(&btr_search_latch); - if (UNIV_UNLIKELY(btr_search_fully_disabled)) { + if (UNIV_UNLIKELY(!btr_search_enabled)) { goto exit_func; } - if (block->is_hashed && ((block->curr_n_fields != n_fields) - || (block->curr_n_bytes != n_bytes) - || (block->curr_left_side != left_side))) { + if (block->index && ((block->curr_n_fields != n_fields) + || (block->curr_n_bytes != n_bytes) + || (block->curr_left_side != left_side))) { goto exit_func; } @@ -1388,11 +1385,10 @@ btr_search_build_page_hash_index( rebuild hash index for a page that is already hashed, we have to take care not to increment the counter in that case. */ - if (!block->is_hashed) { + if (!block->index) { index->search_info->ref_count++; } - block->is_hashed = TRUE; block->n_hash_helps = 0; block->curr_n_fields = n_fields; @@ -1440,14 +1436,15 @@ btr_search_move_or_delete_hash_entries( ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - ut_a(!new_block->is_hashed || new_block->index == index); - ut_a(!block->is_hashed || block->index == index); - ut_a(!(new_block->is_hashed || block->is_hashed) - || !dict_index_is_ibuf(index)); rw_lock_s_lock(&btr_search_latch); - if (new_block->is_hashed) { + ut_a(!new_block->index || new_block->index == index); + ut_a(!block->index || block->index == index); + ut_a(!(new_block->index || block->index) + || !dict_index_is_ibuf(index)); + + if (new_block->index) { rw_lock_s_unlock(&btr_search_latch); @@ -1456,7 +1453,7 @@ btr_search_move_or_delete_hash_entries( return; } - if (block->is_hashed) { + if (block->index) { n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; @@ -1493,42 +1490,48 @@ btr_search_update_hash_on_delete( { hash_table_t* table; buf_block_t* block; - rec_t* rec; + const rec_t* rec; ulint fold; - dulint index_id; + dict_index_t* index; ulint offsets_[REC_OFFS_NORMAL_SIZE]; mem_heap_t* heap = NULL; rec_offs_init(offsets_); - rec = btr_cur_get_rec(cursor); - block = btr_cur_get_block(cursor); #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); + ut_a(index == cursor->index); ut_a(block->curr_n_fields + block->curr_n_bytes > 0); - ut_a(!dict_index_is_ibuf(cursor->index)); + ut_a(!dict_index_is_ibuf(index)); table = btr_search_sys->hash_index; - index_id = cursor->index->id; - fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_, + rec = btr_cur_get_rec(cursor); + + fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap), - block->curr_n_fields, block->curr_n_bytes, index_id); + block->curr_n_fields, block->curr_n_bytes, index->id); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } + rw_lock_x_lock(&btr_search_latch); - ha_search_and_delete_if_found(table, fold, rec); + if (block->index) { + ut_a(block->index == index); + + ha_search_and_delete_if_found(table, fold, rec); + } rw_lock_x_unlock(&btr_search_latch); } @@ -1546,6 +1549,7 @@ btr_search_update_hash_node_on_insert( { hash_table_t* table; buf_block_t* block; + dict_index_t* index; rec_t* rec; rec = btr_cur_get_rec(cursor); @@ -1556,16 +1560,25 @@ btr_search_update_hash_node_on_insert( ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); - ut_a(!dict_index_is_ibuf(cursor->index)); + ut_a(cursor->index == index); + ut_a(!dict_index_is_ibuf(index)); rw_lock_x_lock(&btr_search_latch); + if (!block->index) { + + goto func_exit; + } + + ut_a(block->index == index); + if ((cursor->flag == BTR_CUR_HASH) && (cursor->n_fields == block->curr_n_fields) && (cursor->n_bytes == block->curr_n_bytes) @@ -1576,6 +1589,7 @@ btr_search_update_hash_node_on_insert( ha_search_and_update_if_found(table, cursor->fold, rec, block, page_rec_get_next(rec)); +func_exit: rw_lock_x_unlock(&btr_search_latch); } else { rw_lock_x_unlock(&btr_search_latch); @@ -1597,10 +1611,10 @@ btr_search_update_hash_on_insert( { hash_table_t* table; buf_block_t* block; + dict_index_t* index; rec_t* rec; rec_t* ins_rec; rec_t* next_rec; - dulint index_id; ulint fold; ulint ins_fold; ulint next_fold = 0; /* remove warning (??? bug ???) */ @@ -1625,15 +1639,15 @@ btr_search_update_hash_on_insert( ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ - if (!block->is_hashed) { + index = block->index; + + if (!index) { return; } - ut_a(block->index == cursor->index); - ut_a(!dict_index_is_ibuf(cursor->index)); - - index_id = cursor->index->id; + ut_a(index == cursor->index); + ut_a(!dict_index_is_ibuf(index)); n_fields = block->curr_n_fields; n_bytes = block->curr_n_bytes; @@ -1642,21 +1656,21 @@ btr_search_update_hash_on_insert( ins_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(ins_rec); - offsets = rec_get_offsets(ins_rec, cursor->index, offsets, + offsets = rec_get_offsets(ins_rec, index, offsets, ULINT_UNDEFINED, &heap); - ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index_id); + ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id); if (!page_rec_is_supremum(next_rec)) { - offsets = rec_get_offsets(next_rec, cursor->index, offsets, + offsets = rec_get_offsets(next_rec, index, offsets, n_fields + (n_bytes > 0), &heap); next_fold = rec_fold(next_rec, offsets, n_fields, - n_bytes, index_id); + n_bytes, index->id); } if (!page_rec_is_infimum(rec)) { - offsets = rec_get_offsets(rec, cursor->index, offsets, + offsets = rec_get_offsets(rec, index, offsets, n_fields + (n_bytes > 0), &heap); - fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id); + fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id); } else { if (left_side) { @@ -1664,6 +1678,10 @@ btr_search_update_hash_on_insert( locked = TRUE; + if (!btr_search_enabled) { + goto function_exit; + } + ha_insert_for_fold(table, ins_fold, block, ins_rec); } @@ -1677,6 +1695,10 @@ btr_search_update_hash_on_insert( rw_lock_x_lock(&btr_search_latch); locked = TRUE; + + if (!btr_search_enabled) { + goto function_exit; + } } if (!left_side) { @@ -1695,6 +1717,10 @@ check_next_rec: rw_lock_x_lock(&btr_search_latch); locked = TRUE; + + if (!btr_search_enabled) { + goto function_exit; + } } ha_insert_for_fold(table, ins_fold, block, ins_rec); @@ -1710,6 +1736,10 @@ check_next_rec: rw_lock_x_lock(&btr_search_latch); locked = TRUE; + + if (!btr_search_enabled) { + goto function_exit; + } } if (!left_side) { @@ -1717,7 +1747,7 @@ check_next_rec: ha_insert_for_fold(table, ins_fold, block, ins_rec); /* fputs("Hash insert for ", stderr); - dict_index_name_print(stderr, cursor->index); + dict_index_name_print(stderr, index); fprintf(stderr, " fold %lu\n", ins_fold); */ } else { @@ -1821,7 +1851,7 @@ btr_search_validate(void) + (block->curr_n_bytes > 0), &heap); - if (!block->is_hashed || node->fold + if (!block->index || node->fold != rec_fold((rec_t*)(node->data), offsets, block->curr_n_fields, @@ -1856,10 +1886,10 @@ btr_search_validate(void) rec_print_new(stderr, (rec_t*)node->data, offsets); fprintf(stderr, "\nInnoDB: on that page." - " Page mem address %p, is hashed %lu," + " Page mem address %p, is hashed %p," " n fields %lu, n bytes %lu\n" "InnoDB: side %lu\n", - (void*) page, (ulong) block->is_hashed, + (void*) page, (void*) block->index, (ulong) block->curr_n_fields, (ulong) block->curr_n_bytes, (ulong) block->curr_left_side); diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 47300627acc..7d03f08f61f 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -962,86 +962,42 @@ buf_pool_free(void) } /********************************************************************//** -Drops the adaptive hash index. To prevent a livelock, this function -is only to be called while holding btr_search_latch and while -btr_search_enabled == FALSE. */ +Clears the adaptive hash index on all pages in the buffer pool. */ UNIV_INTERN void -buf_pool_drop_hash_index(void) -/*==========================*/ +buf_pool_clear_hash_index(void) +/*===========================*/ { - ibool released_search_latch; + buf_chunk_t* chunks = buf_pool->chunks; + buf_chunk_t* chunk = chunks + buf_pool->n_chunks; #ifdef UNIV_SYNC_DEBUG ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); #endif /* UNIV_SYNC_DEBUG */ ut_ad(!btr_search_enabled); - do { - buf_chunk_t* chunks = buf_pool->chunks; - buf_chunk_t* chunk = chunks + buf_pool->n_chunks; - - released_search_latch = FALSE; + while (--chunk >= chunks) { + buf_block_t* block = chunk->blocks; + ulint i = chunk->size; - while (--chunk >= chunks) { - buf_block_t* block = chunk->blocks; - ulint i = chunk->size; + for (; i--; block++) { + dict_index_t* index = block->index; - for (; i--; block++) { - /* block->is_hashed cannot be modified - when we have an x-latch on btr_search_latch; - see the comment in buf0buf.h */ + /* We can set block->index = NULL + when we have an x-latch on btr_search_latch; + see the comment in buf0buf.h */ - if (buf_block_get_state(block) - != BUF_BLOCK_FILE_PAGE - || !block->is_hashed) { - continue; - } - - /* To follow the latching order, we - have to release btr_search_latch - before acquiring block->latch. */ - rw_lock_x_unlock(&btr_search_latch); - /* When we release the search latch, - we must rescan all blocks, because - some may become hashed again. */ - released_search_latch = TRUE; - - rw_lock_x_lock(&block->lock); - - /* This should be guaranteed by the - callers, which will be holding - btr_search_enabled_mutex. */ - ut_ad(!btr_search_enabled); - - /* Because we did not buffer-fix the - block by calling buf_block_get_gen(), - it is possible that the block has been - allocated for some other use after - btr_search_latch was released above. - We do not care which file page the - block is mapped to. All we want to do - is to drop any hash entries referring - to the page. */ - - /* It is possible that - block->page.state != BUF_FILE_PAGE. - Even that does not matter, because - btr_search_drop_page_hash_index() will - check block->is_hashed before doing - anything. block->is_hashed can only - be set on uncompressed file pages. */ - - btr_search_drop_page_hash_index(block); - - rw_lock_x_unlock(&block->lock); - - rw_lock_x_lock(&btr_search_latch); - - ut_ad(!btr_search_enabled); + if (!index) { + /* Not hashed */ + continue; } + + block->index = NULL; +# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG + block->n_pointers = 0; +# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ } - } while (released_search_latch); + } } /********************************************************************//** @@ -1174,36 +1130,6 @@ buf_page_set_accessed_make_young( } } -/********************************************************************//** -Returns the current state of is_hashed of a page. FALSE if the page is -not in the pool. NOTE that this operation does not fix the page in the -pool if it is found there. -@return TRUE if page hash index is built in search system */ -UNIV_INTERN -ibool -buf_page_peek_if_search_hashed( -/*===========================*/ - ulint space, /*!< in: space id */ - ulint offset) /*!< in: page number */ -{ - buf_block_t* block; - ibool is_hashed; - - buf_pool_mutex_enter(); - - block = (buf_block_t*) buf_page_hash_get(space, offset); - - if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) { - is_hashed = FALSE; - } else { - is_hashed = block->is_hashed; - } - - buf_pool_mutex_exit(); - - return(is_hashed); -} - #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG /********************************************************************//** Sets file_page_was_freed TRUE if the page is found in the buffer pool. @@ -1408,7 +1334,6 @@ buf_block_init_low( block->index = NULL; block->n_hash_helps = 0; - block->is_hashed = FALSE; block->n_fields = 1; block->n_bytes = 0; block->left_side = TRUE; diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c index ad6feef5f2f..5124787eba1 100644 --- a/storage/innodb_plugin/buf/buf0lru.c +++ b/storage/innodb_plugin/buf/buf0lru.c @@ -272,7 +272,7 @@ next_page: mutex_enter(&((buf_block_t*) bpage)->mutex); is_fixed = bpage->buf_fix_count > 0 - || !((buf_block_t*) bpage)->is_hashed; + || !((buf_block_t*) bpage)->index; mutex_exit(&((buf_block_t*) bpage)->mutex); if (is_fixed) { @@ -407,7 +407,7 @@ scan_again: if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) { /* This is a compressed-only block descriptor. Do nothing. */ - } else if (((buf_block_t*) bpage)->is_hashed) { + } else if (((buf_block_t*) bpage)->index) { ulint page_no; ulint zip_size; @@ -419,7 +419,7 @@ scan_again: mutex_exit(block_mutex); /* Note that the following call will acquire - an S-latch on the page */ + and release an X-latch on the page. */ btr_search_drop_page_hash_when_freed( id, zip_size, page_no); diff --git a/storage/innodb_plugin/ha/ha0ha.c b/storage/innodb_plugin/ha/ha0ha.c index 7f11917de0a..65046138275 100644 --- a/storage/innodb_plugin/ha/ha0ha.c +++ b/storage/innodb_plugin/ha/ha0ha.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -89,40 +89,6 @@ ha_create_func( } /*************************************************************//** -Empties a hash table and frees the memory heaps. */ -UNIV_INTERN -void -ha_clear( -/*=====*/ - hash_table_t* table) /*!< in, own: hash table */ -{ - ulint i; - ulint n; - - ut_ad(table); - ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); -#ifdef UNIV_SYNC_DEBUG - ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE)); -#endif /* UNIV_SYNC_DEBUG */ - -#ifndef UNIV_HOTBACKUP - /* Free the memory heaps. */ - n = table->n_mutexes; - - for (i = 0; i < n; i++) { - mem_heap_free(table->heaps[i]); - } -#endif /* !UNIV_HOTBACKUP */ - - /* Clear the hash table. */ - n = hash_get_n_cells(table); - - for (i = 0; i < n; i++) { - hash_get_nth_cell(table, i)->node = NULL; - } -} - -/*************************************************************//** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node is inserted. If btr_search_enabled is set to FALSE, we will only allow @@ -140,7 +106,7 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data) /*!< in: data, must not be NULL */ + const rec_t* data) /*!< in: data, must not be NULL */ { hash_cell_t* cell; ha_node_t* node; @@ -153,7 +119,11 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG ut_a(block->frame == page_align(data)); #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ ASSERT_HASH_MUTEX_OWN(table, fold); + ut_ad(btr_search_enabled); hash = hash_calc_hash(fold, table); @@ -173,7 +143,6 @@ ha_insert_for_fold_func( prev_block->n_pointers--; block->n_pointers++; } - ut_ad(!btr_search_fully_disabled); # endif /* !UNIV_HOTBACKUP */ prev_node->block = block; @@ -186,13 +155,6 @@ ha_insert_for_fold_func( prev_node = prev_node->next; } - /* We are in the process of disabling hash index, do not add - new chain node */ - if (!btr_search_enabled) { - ut_ad(!btr_search_fully_disabled); - return(TRUE); - } - /* We have to allocate a new chain node */ node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t)); @@ -250,6 +212,10 @@ ha_delete_hash_node( { ut_ad(table); ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG # ifndef UNIV_HOTBACKUP if (table->adaptive) { @@ -272,11 +238,11 @@ ha_search_and_update_if_found_func( /*===============================*/ hash_table_t* table, /*!< in/out: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data, /*!< in: pointer to the data */ + const rec_t* data, /*!< in: pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* new_block,/*!< in: block containing new_data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* new_data)/*!< in: new pointer to the data */ + const rec_t* new_data)/*!< in: new pointer to the data */ { ha_node_t* node; @@ -286,6 +252,13 @@ ha_search_and_update_if_found_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG ut_a(new_block->frame == page_align(new_data)); #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + + if (!btr_search_enabled) { + return; + } node = ha_search_with_data(table, fold, data); @@ -322,6 +295,10 @@ ha_remove_all_nodes_to_page( ut_ad(table); ut_ad(table->magic_n == HASH_TABLE_MAGIC_N); ASSERT_HASH_MUTEX_OWN(table, fold); +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); node = ha_chain_get_first(table, fold); diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index aec0e77768c..fc1193e55bb 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -2304,7 +2304,6 @@ innobase_change_buffering_inited_ok: /* Get the current high water mark format. */ innobase_file_format_check = (char*) trx_sys_file_format_max_get(); - btr_search_fully_disabled = (!btr_search_enabled); DBUG_RETURN(FALSE); error: DBUG_RETURN(TRUE); diff --git a/storage/innodb_plugin/ibuf/ibuf0ibuf.c b/storage/innodb_plugin/ibuf/ibuf0ibuf.c index e4d8f79a944..a22de3b0e70 100644 --- a/storage/innodb_plugin/ibuf/ibuf0ibuf.c +++ b/storage/innodb_plugin/ibuf/ibuf0ibuf.c @@ -2971,7 +2971,7 @@ ibuf_insert_to_index_page( ut_ad(ibuf_inside()); ut_ad(dtuple_check_typed(entry)); - ut_ad(!buf_block_align(page)->is_hashed); + ut_ad(!buf_block_align(page)->index); if (UNIV_UNLIKELY(dict_table_is_comp(index->table) != (ibool)!!page_is_comp(page))) { diff --git a/storage/innodb_plugin/include/btr0sea.h b/storage/innodb_plugin/include/btr0sea.h index 6493689a969..1f920471f7d 100644 --- a/storage/innodb_plugin/include/btr0sea.h +++ b/storage/innodb_plugin/include/btr0sea.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -141,8 +141,8 @@ btr_search_drop_page_hash_index( for which we know that block->buf_fix_count == 0 */ /********************************************************************//** -Drops a page hash index when a page is freed from a fseg to the file system. -Drops possible hash index if the page happens to be in the buffer pool. */ +Drops a possible page hash index when a page is evicted from the buffer pool +or freed in a file segment. */ UNIV_INTERN void btr_search_drop_page_hash_when_freed( @@ -192,16 +192,6 @@ btr_search_validate(void); # define btr_search_validate() TRUE #endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */ -/** Flag: has the search system been enabled? -Protected by btr_search_latch and btr_search_enabled_mutex. */ -extern char btr_search_enabled; - -/** Flag: whether the search system has completed its disabling process, -It is set to TRUE right after buf_pool_drop_hash_index() in -btr_search_disable(), indicating hash index entries are cleaned up. -Protected by btr_search_latch and btr_search_enabled_mutex. */ -extern ibool btr_search_fully_disabled; - /** The search info struct in an index */ struct btr_search_struct{ ulint ref_count; /*!< Number of blocks in this index tree @@ -270,24 +260,6 @@ struct btr_search_sys_struct{ /** The adaptive hash index */ extern btr_search_sys_t* btr_search_sys; -/** @brief The latch protecting the adaptive search system - -This latch protects the -(1) hash index; -(2) columns of a record to which we have a pointer in the hash index; - -but does NOT protect: - -(3) next record offset field in a record; -(4) next or previous records on the same page. - -Bear in mind (3) and (4) when using the hash index. -*/ -extern rw_lock_t* btr_search_latch_temp; - -/** The latch protecting the adaptive search system */ -#define btr_search_latch (*btr_search_latch_temp) - #ifdef UNIV_SEARCH_PERF_STAT /** Number of successful adaptive hash index lookups */ extern ulint btr_search_n_succ; diff --git a/storage/innodb_plugin/include/btr0types.h b/storage/innodb_plugin/include/btr0types.h index 07c06fb18d7..5adc858b931 100644 --- a/storage/innodb_plugin/include/btr0types.h +++ b/storage/innodb_plugin/include/btr0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -30,6 +30,7 @@ Created 2/17/1996 Heikki Tuuri #include "rem0types.h" #include "page0types.h" +#include "sync0rw.h" /** Persistent cursor */ typedef struct btr_pcur_struct btr_pcur_t; @@ -38,6 +39,28 @@ typedef struct btr_cur_struct btr_cur_t; /** B-tree search information for the adaptive hash index */ typedef struct btr_search_struct btr_search_t; +/** @brief The latch protecting the adaptive search system + +This latch protects the +(1) hash index; +(2) columns of a record to which we have a pointer in the hash index; + +but does NOT protect: + +(3) next record offset field in a record; +(4) next or previous records on the same page. + +Bear in mind (3) and (4) when using the hash index. +*/ +extern rw_lock_t* btr_search_latch_temp; + +/** The latch protecting the adaptive search system */ +#define btr_search_latch (*btr_search_latch_temp) + +/** Flag: has the search system been enabled? +Protected by btr_search_latch. */ +extern char btr_search_enabled; + #ifdef UNIV_BLOB_DEBUG # include "buf0types.h" /** An index->blobs entry for keeping track of off-page column references */ diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h index 557bc17d311..e7fe3901ad4 100644 --- a/storage/innodb_plugin/include/buf0buf.h +++ b/storage/innodb_plugin/include/buf0buf.h @@ -120,13 +120,11 @@ buf_pool_free(void); /*===============*/ /********************************************************************//** -Drops the adaptive hash index. To prevent a livelock, this function -is only to be called while holding btr_search_latch and while -btr_search_enabled == FALSE. */ +Clears the adaptive hash index on all pages in the buffer pool. */ UNIV_INTERN void -buf_pool_drop_hash_index(void); -/*==========================*/ +buf_pool_clear_hash_index(void); +/*===========================*/ /********************************************************************//** Relocate a buffer control block. Relocates the block on the LRU list @@ -440,17 +438,6 @@ buf_page_peek_if_too_old( /*=====================*/ const buf_page_t* bpage); /*!< in: block to make younger */ /********************************************************************//** -Returns the current state of is_hashed of a page. FALSE if the page is -not in the pool. NOTE that this operation does not fix the page in the -pool if it is found there. -@return TRUE if page hash index is built in search system */ -UNIV_INTERN -ibool -buf_page_peek_if_search_hashed( -/*===========================*/ - ulint space, /*!< in: space id */ - ulint offset);/*!< in: page number */ -/********************************************************************//** Gets the youngest modification log sequence number for a frame. Returns zero if not file page or no modification occurred yet. @return newest modification to page */ @@ -1267,13 +1254,16 @@ struct buf_block_struct{ /* @} */ /** @name Hash search fields - These 6 fields may only be modified when we have + These 5 fields may only be modified when we have an x-latch on btr_search_latch AND - we are holding an s-latch or x-latch on buf_block_struct::lock or - we know that buf_block_struct::buf_fix_count == 0. An exception to this is when we init or create a page - in the buffer pool in buf0buf.c. */ + in the buffer pool in buf0buf.c. + + Another exception is that assigning block->index = NULL + is allowed whenever holding an x-latch on btr_search_latch. */ /* @{ */ @@ -1282,20 +1272,20 @@ struct buf_block_struct{ pointers in the adaptive hash index pointing to this frame */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - unsigned is_hashed:1; /*!< TRUE if hash index has - already been built on this - page; note that it does not - guarantee that the index is - complete, though: there may - have been hash collisions, - record deletions, etc. */ unsigned curr_n_fields:10;/*!< prefix length for hash indexing: number of full fields */ unsigned curr_n_bytes:15;/*!< number of bytes in hash indexing */ unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */ - dict_index_t* index; /*!< Index for which the adaptive - hash index has been created. */ + dict_index_t* index; /*!< Index for which the + adaptive hash index has been + created, or NULL if the page + does not exist in the + index. Note that it does not + guarantee that the index is + complete, though: there may + have been hash collisions, + record deletions, etc. */ /* @} */ # ifdef UNIV_SYNC_DEBUG /** @name Debug fields */ diff --git a/storage/innodb_plugin/include/ha0ha.h b/storage/innodb_plugin/include/ha0ha.h index 3299000bf3c..8bba564d153 100644 --- a/storage/innodb_plugin/include/ha0ha.h +++ b/storage/innodb_plugin/include/ha0ha.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -31,13 +31,14 @@ Created 8/18/1994 Heikki Tuuri #include "hash0hash.h" #include "page0types.h" #include "buf0types.h" +#include "rem0types.h" /*************************************************************//** Looks for an element in a hash table. @return pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ UNIV_INLINE -void* +const rec_t* ha_search_and_get_data( /*===================*/ hash_table_t* table, /*!< in: hash table */ @@ -51,11 +52,11 @@ ha_search_and_update_if_found_func( /*===============================*/ hash_table_t* table, /*!< in/out: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data, /*!< in: pointer to the data */ + const rec_t* data, /*!< in: pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* new_block,/*!< in: block containing new_data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* new_data);/*!< in: new pointer to the data */ + const rec_t* new_data);/*!< in: new pointer to the data */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /** Looks for an element when we know the pointer to the data and @@ -114,14 +115,6 @@ chosen to be a slightly bigger prime number. #endif /* UNIV_SYNC_DEBUG */ /*************************************************************//** -Empties a hash table and frees the memory heaps. */ -UNIV_INTERN -void -ha_clear( -/*=====*/ - hash_table_t* table); /*!< in, own: hash table */ - -/*************************************************************//** Inserts an entry into a hash table. If an entry with the same fold number is found, its node is updated to point to the new data, and no new node is inserted. @@ -138,7 +131,7 @@ ha_insert_for_fold_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data); /*!< in: data, must not be NULL */ + const rec_t* data); /*!< in: data, must not be NULL */ #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG /** @@ -174,7 +167,7 @@ ha_search_and_delete_if_found( /*==========================*/ hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data); /*!< in: pointer to the data */ + const rec_t* data); /*!< in: pointer to the data */ #ifndef UNIV_HOTBACKUP /*****************************************************************//** Removes from the chain determined by fold all nodes whose data pointer @@ -217,7 +210,7 @@ struct ha_node_struct { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block; /*!< buffer block containing the data, or NULL */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data; /*!< pointer to the data */ + const rec_t* data; /*!< pointer to the data */ ulint fold; /*!< fold value for the data */ }; diff --git a/storage/innodb_plugin/include/ha0ha.ic b/storage/innodb_plugin/include/ha0ha.ic index 734403c4cd9..5656e9b7eba 100644 --- a/storage/innodb_plugin/include/ha0ha.ic +++ b/storage/innodb_plugin/include/ha0ha.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved. +Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -25,6 +25,7 @@ Created 8/18/1994 Heikki Tuuri #include "ut0rnd.h" #include "mem0mem.h" +#include "btr0types.h" /***********************************************************//** Deletes a hash node. */ @@ -39,10 +40,10 @@ ha_delete_hash_node( Gets a hash node data. @return pointer to the data */ UNIV_INLINE -void* +const rec_t* ha_node_get_data( /*=============*/ - ha_node_t* node) /*!< in: hash chain node */ + const ha_node_t* node) /*!< in: hash chain node */ { return(node->data); } @@ -57,7 +58,7 @@ ha_node_set_data_func( #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG buf_block_t* block, /*!< in: buffer block containing the data */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ - void* data) /*!< in: pointer to the data */ + const rec_t* data) /*!< in: pointer to the data */ { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG node->block = block; @@ -107,39 +108,10 @@ ha_chain_get_first( /*************************************************************//** Looks for an element in a hash table. -@return pointer to the first hash table node in chain having the fold -number, NULL if not found */ -UNIV_INLINE -ha_node_t* -ha_search( -/*======*/ - hash_table_t* table, /*!< in: hash table */ - ulint fold) /*!< in: folded value of the searched data */ -{ - ha_node_t* node; - - ASSERT_HASH_MUTEX_OWN(table, fold); - - node = ha_chain_get_first(table, fold); - - while (node) { - if (node->fold == fold) { - - return(node); - } - - node = ha_chain_get_next(node); - } - - return(NULL); -} - -/*************************************************************//** -Looks for an element in a hash table. @return pointer to the data of the first hash table node in chain having the fold number, NULL if not found */ UNIV_INLINE -void* +const rec_t* ha_search_and_get_data( /*===================*/ hash_table_t* table, /*!< in: hash table */ @@ -148,6 +120,10 @@ ha_search_and_get_data( ha_node_t* node; ASSERT_HASH_MUTEX_OWN(table, fold); +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); node = ha_chain_get_first(table, fold); @@ -172,12 +148,14 @@ ha_search_with_data( /*================*/ hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data) /*!< in: pointer to the data */ + const rec_t* data) /*!< in: pointer to the data */ { ha_node_t* node; ASSERT_HASH_MUTEX_OWN(table, fold); + ut_ad(btr_search_enabled); + node = ha_chain_get_first(table, fold); while (node) { @@ -202,11 +180,15 @@ ha_search_and_delete_if_found( /*==========================*/ hash_table_t* table, /*!< in: hash table */ ulint fold, /*!< in: folded value of the searched data */ - void* data) /*!< in: pointer to the data */ + const rec_t* data) /*!< in: pointer to the data */ { ha_node_t* node; ASSERT_HASH_MUTEX_OWN(table, fold); +#ifdef UNIV_SYNC_DEBUG + ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX)); +#endif /* UNIV_SYNC_DEBUG */ + ut_ad(btr_search_enabled); node = ha_search_with_data(table, fold, data); diff --git a/storage/innodb_plugin/include/row0upd.ic b/storage/innodb_plugin/include/row0upd.ic index 11db82f64da..10646241125 100644 --- a/storage/innodb_plugin/include/row0upd.ic +++ b/storage/innodb_plugin/include/row0upd.ic @@ -28,7 +28,6 @@ Created 12/27/1996 Heikki Tuuri # include "trx0trx.h" # include "trx0undo.h" # include "row0row.h" -# include "btr0sea.h" #endif /* !UNIV_HOTBACKUP */ #include "page0zip.h" diff --git a/storage/innodb_plugin/include/sync0sync.h b/storage/innodb_plugin/include/sync0sync.h index f2013c202c1..63bad29a9c8 100644 --- a/storage/innodb_plugin/include/sync0sync.h +++ b/storage/innodb_plugin/include/sync0sync.h @@ -481,7 +481,6 @@ or row lock! */ #define SYNC_LOG 170 #define SYNC_RECV 168 #define SYNC_WORK_QUEUE 162 -#define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */ #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory heap that can be extended to the buffer pool, its logical level is diff --git a/storage/innodb_plugin/page/page0page.c b/storage/innodb_plugin/page/page0page.c index a284b1480a3..1b9470acbbc 100644 --- a/storage/innodb_plugin/page/page0page.c +++ b/storage/innodb_plugin/page/page0page.c @@ -215,12 +215,6 @@ page_set_max_trx_id( { page_t* page = buf_block_get_frame(block); #ifndef UNIV_HOTBACKUP - const ibool is_hashed = block->is_hashed; - - if (is_hashed) { - rw_lock_x_lock(&btr_search_latch); - } - ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); #endif /* !UNIV_HOTBACKUP */ @@ -241,12 +235,6 @@ page_set_max_trx_id( } else { mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id); } - -#ifndef UNIV_HOTBACKUP - if (is_hashed) { - rw_lock_x_unlock(&btr_search_latch); - } -#endif /* !UNIV_HOTBACKUP */ } /************************************************************//** diff --git a/storage/innodb_plugin/sync/sync0sync.c b/storage/innodb_plugin/sync/sync0sync.c index 3640e204525..3e66aaafef2 100644 --- a/storage/innodb_plugin/sync/sync0sync.c +++ b/storage/innodb_plugin/sync/sync0sync.c @@ -1160,7 +1160,6 @@ sync_thread_add_level( case SYNC_DOUBLEWRITE: case SYNC_BUF_POOL: case SYNC_SEARCH_SYS: - case SYNC_SEARCH_SYS_CONF: case SYNC_TRX_LOCK_HEAP: case SYNC_KERNEL: case SYNC_IBUF_BITMAP_MUTEX: |