#!!! notice !!!
# Any small change to this file in the main branch
# should be done or reviewed by the maintainer!
---- a/storage/innobase/btr/btr0btr.c
-+++ b/storage/innobase/btr/btr0btr.c
-@@ -1523,7 +1523,7 @@
- }
- ut_a(block);
-
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, NULL);
-
- header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
- #ifdef UNIV_BTR_DEBUG
-@@ -1592,7 +1592,7 @@
-
- #ifndef UNIV_HOTBACKUP
- if (UNIV_LIKELY(!recovery)) {
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
- }
-
- block->check_index_page_at_flush = TRUE;
-@@ -1760,7 +1760,7 @@
- ut_a(!page_zip || page_zip_validate(page_zip, page));
- #endif /* UNIV_ZIP_DEBUG */
-
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
- btr_blob_dbg_remove(page, index, "btr_page_empty");
-
- /* Recreate the page: note that global data on page (possible
-@@ -3093,7 +3093,7 @@
- mem_heap_free(heap);
- }
-
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
-
- /* Make the father empty */
- btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
-@@ -3317,7 +3317,7 @@
- goto err_exit;
- }
-
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
-
- /* Remove the page from the level list */
- btr_level_list_remove(space, zip_size, page, index, mtr);
-@@ -3358,7 +3358,7 @@
- goto err_exit;
- }
-
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
-
- #ifdef UNIV_BTR_DEBUG
- if (UNIV_LIKELY_NULL(merge_page_zip)) {
-@@ -3473,7 +3473,7 @@
- ut_a(btr_page_get_next(page, mtr) == FIL_NULL);
-
- ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
-
- btr_page_get_father(index, block, mtr, &cursor);
- father = btr_cur_get_block(&cursor);
-@@ -3578,7 +3578,7 @@
-
- page = buf_block_get_frame(block);
- ut_a(page_is_comp(merge_page) == page_is_comp(page));
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
-
- if (left_page_no == FIL_NULL && !page_is_leaf(page)) {
-
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -500,7 +500,7 @@
}
failure:
cursor->flag = BTR_CUR_HASH_FAIL;
-@@ -1032,10 +1063,11 @@
- void
- btr_search_drop_page_hash_index(
- /*============================*/
-- buf_block_t* block) /*!< in: block containing index page,
-+ buf_block_t* block, /*!< in: block containing index page,
- s- or x-latched, or an index page
- for which we know that
- block->buf_fix_count == 0 */
-+ dict_index_t* index_in)
- {
- hash_table_t* table;
- ulint n_fields;
-@@ -1054,23 +1086,55 @@
+@@ -1053,24 +1084,49 @@
+ const dict_index_t* index;
ulint* offsets;
- #ifdef UNIV_SYNC_DEBUG
+-#ifdef UNIV_SYNC_DEBUG
- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
- ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
-+ if (index_in) {
-+ ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_SHARED));
-+ ut_ad(!rw_lock_own(btr_search_get_latch(index_in->id), RW_LOCK_EX));
-+ }
- #endif /* UNIV_SYNC_DEBUG */
-
+-#endif /* UNIV_SYNC_DEBUG */
+-
retry:
- rw_lock_s_lock(&btr_search_latch);
- index = block->index;
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
-@@ -1080,12 +1144,14 @@
+@@ -1080,12 +1136,14 @@
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
ut_a(n_fields + n_bytes > 0);
-@@ -1136,7 +1202,7 @@
+@@ -1136,7 +1194,7 @@
mem_heap_free(heap);
}
if (UNIV_UNLIKELY(!block->index)) {
/* Someone else has meanwhile dropped the hash index */
-@@ -1152,7 +1218,7 @@
+@@ -1152,7 +1210,7 @@
/* Someone else has meanwhile built a new hash index on the
page, with different parameters */
mem_free(folds);
goto retry;
-@@ -1167,6 +1233,7 @@
+@@ -1167,6 +1225,7 @@
index->search_info->ref_count--;
block->index = NULL;
cleanup:
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-@@ -1179,14 +1246,14 @@
+@@ -1179,14 +1238,14 @@
"InnoDB: the hash index to a page of %s,"
" still %lu hash nodes remain.\n",
index->name, (ulong) block->n_pointers);
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
mem_free(folds);
-@@ -1218,9 +1285,9 @@
+@@ -1218,9 +1277,9 @@
ulint* offsets;
ibool released_search_latch;
for (j = 0; j < srv_buf_pool_instances; j++) {
buf_pool_t* buf_pool;
-@@ -1254,7 +1321,7 @@
+@@ -1254,7 +1313,7 @@
/* keeping latch order */
released_search_latch = TRUE;
rw_lock_x_lock(&block->lock);
-@@ -1306,7 +1373,7 @@
+@@ -1306,7 +1365,7 @@
mem_heap_empty(heap);
}
if (UNIV_UNLIKELY(!block->index)) {
goto cleanup;
-@@ -1316,12 +1383,12 @@
+@@ -1316,12 +1375,12 @@
if (UNIV_UNLIKELY(block->curr_n_fields != n_fields)
|| UNIV_UNLIKELY(block->curr_n_bytes != n_bytes)) {
goto retry;
}
-@@ -1334,6 +1401,7 @@
+@@ -1334,6 +1393,7 @@
index->search_info->ref_count--;
block->index = NULL;
cleanup:
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-@@ -1346,18 +1414,18 @@
+@@ -1346,18 +1406,18 @@
index->name, (ulong) block->n_pointers);
}
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
-@@ -1395,7 +1463,7 @@
-
- buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
-
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, NULL);
- }
-
- mtr_commit(&mtr);
-@@ -1436,31 +1504,26 @@
+@@ -1436,31 +1496,26 @@
ut_ad(index);
ut_a(!dict_index_is_ibuf(index));
- rw_lock_s_unlock(&btr_search_latch);
+ rw_lock_s_unlock(btr_search_get_latch(index->id));
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
+ btr_search_drop_page_hash_index(block);
} else {
- rw_lock_s_unlock(&btr_search_latch);
+ rw_lock_s_unlock(btr_search_get_latch(index->id));
}
n_recs = page_get_n_recs(page);
-@@ -1554,9 +1617,9 @@
+@@ -1554,9 +1609,9 @@
fold = next_fold;
}
if (UNIV_UNLIKELY(!btr_search_enabled)) {
goto exit_func;
-@@ -1583,6 +1646,7 @@
+@@ -1583,6 +1638,7 @@
block->curr_n_bytes = n_bytes;
block->curr_left_side = left_side;
block->index = index;
for (i = 0; i < n_cached; i++) {
-@@ -1590,7 +1654,7 @@
+@@ -1590,7 +1646,7 @@
}
exit_func:
mem_free(folds);
mem_free(recs);
-@@ -1625,7 +1689,7 @@
+@@ -1625,7 +1681,7 @@
ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
ut_a(!new_block->index || new_block->index == index);
ut_a(!block->index || block->index == index);
-@@ -1634,9 +1698,9 @@
+@@ -1634,7 +1690,7 @@
if (new_block->index) {
- rw_lock_s_unlock(&btr_search_latch);
+ rw_lock_s_unlock(btr_search_get_latch(index->id));
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
+ btr_search_drop_page_hash_index(block);
- return;
- }
-@@ -1651,7 +1715,7 @@
+@@ -1651,7 +1707,7 @@
new_block->n_bytes = block->curr_n_bytes;
new_block->left_side = left_side;
ut_a(n_fields + n_bytes > 0);
-@@ -1663,7 +1727,7 @@
+@@ -1663,7 +1719,7 @@
return;
}
}
/********************************************************************//**
-@@ -1702,7 +1766,7 @@
+@@ -1702,7 +1758,7 @@
ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
ut_a(!dict_index_is_ibuf(index));
rec = btr_cur_get_rec(cursor);
-@@ -1713,7 +1777,7 @@
+@@ -1713,7 +1769,7 @@
mem_heap_free(heap);
}
if (block->index) {
ut_a(block->index == index);
-@@ -1721,7 +1785,7 @@
+@@ -1721,7 +1777,7 @@
ha_search_and_delete_if_found(table, fold, rec);
}
}
/********************************************************************//**
-@@ -1758,7 +1822,7 @@
+@@ -1758,7 +1814,7 @@
ut_a(cursor->index == index);
ut_a(!dict_index_is_ibuf(index));
if (!block->index) {
-@@ -1772,15 +1836,15 @@
+@@ -1772,15 +1828,15 @@
&& (cursor->n_bytes == block->curr_n_bytes)
&& !block->curr_left_side) {
btr_search_update_hash_on_insert(cursor);
}
-@@ -1815,9 +1879,9 @@
+@@ -1815,9 +1871,9 @@
ulint* offsets = offsets_;
rec_offs_init(offsets_);
rec = btr_cur_get_rec(cursor);
-@@ -1862,7 +1926,7 @@
+@@ -1862,7 +1918,7 @@
} else {
if (left_side) {
locked = TRUE;
-@@ -1880,7 +1944,7 @@
+@@ -1880,7 +1936,7 @@
if (!locked) {
locked = TRUE;
-@@ -1902,7 +1966,7 @@
+@@ -1902,7 +1958,7 @@
if (!left_side) {
if (!locked) {
locked = TRUE;
-@@ -1921,7 +1985,7 @@
+@@ -1921,7 +1977,7 @@
if (!locked) {
locked = TRUE;
-@@ -1948,7 +2012,7 @@
+@@ -1948,7 +2004,7 @@
mem_heap_free(heap);
}
if (locked) {
}
}
-@@ -1964,7 +2028,7 @@
+@@ -1964,7 +2020,7 @@
ha_node_t* node;
ulint n_page_dumps = 0;
ibool ok = TRUE;
ulint cell_count;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
-@@ -1976,23 +2040,25 @@
+@@ -1976,23 +2032,25 @@
rec_offs_init(offsets_);
for (; node != NULL; node = node->next) {
const buf_block_t* block
-@@ -2099,19 +2165,21 @@
+@@ -2099,19 +2157,21 @@
give other queries a chance to run. */
if (i != 0) {
buf_pool_page_hash_x_unlock_all();
+ btr_search_s_unlock_all();
rw_lock_x_lock(&block->lock);
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, NULL);
+ btr_search_drop_page_hash_index(block);
rw_lock_x_unlock(&block->lock);
- rw_lock_s_lock(&btr_search_latch);
}
}
-@@ -1744,7 +1744,7 @@
-
- UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
- UNIV_PAGE_SIZE);
-- btr_search_drop_page_hash_index((buf_block_t*) bpage);
-+ btr_search_drop_page_hash_index((buf_block_t*) bpage, NULL);
- UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
- UNIV_PAGE_SIZE);
-
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1846,7 +1846,7 @@
static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
PLUGIN_VAR_RQCMDARG,
"Replication thread delay (ms) on the slave server if "
-@@ -12213,6 +12218,7 @@
+@@ -12253,6 +12258,7 @@
MYSQL_SYSVAR(use_sys_stats_table),
MYSQL_SYSVAR(stats_sample_pages),
MYSQL_SYSVAR(adaptive_hash_index),
/*********************************************************************//**
Updates the search info. */
UNIV_INLINE
-@@ -136,10 +137,11 @@
- void
- btr_search_drop_page_hash_index(
- /*============================*/
-- buf_block_t* block); /*!< in: block containing index page,
-+ buf_block_t* block, /*!< in: block containing index page,
- s- or x-latched, or an index page
- for which we know that
- block->buf_fix_count == 0 */
-+ dict_index_t* index_in);
- /************************************************************************
- Drops a page hash index based on index */
- UNIV_INTERN
-@@ -199,6 +201,40 @@
+@@ -199,6 +200,40 @@
# define btr_search_validate() TRUE
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
/** The search info struct in an index */
struct btr_search_struct{
ulint ref_count; /*!< Number of blocks in this index tree
-@@ -259,7 +295,7 @@
+@@ -259,7 +294,7 @@
/** The hash index system */
struct btr_search_sys_struct{
+ }
+}
+
---- a/storage/innobase/page/page0zip.c
-+++ b/storage/innobase/page/page0zip.c
-@@ -4456,7 +4456,7 @@
-
- #ifndef UNIV_HOTBACKUP
- temp_block = buf_block_alloc(buf_pool);
-- btr_search_drop_page_hash_index(block);
-+ btr_search_drop_page_hash_index(block, index);
- block->check_index_page_at_flush = TRUE;
- #else /* !UNIV_HOTBACKUP */
- ut_ad(block == back_block1);
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -2594,7 +2594,7 @@
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
-@@ -2051,7 +2051,9 @@
+@@ -2054,7 +2054,9 @@
"-------------------------------------\n", file);
ibuf_print(file);
fprintf(file,
"%.2f hash searches/s, %.2f non-hash searches/s\n",
-@@ -2076,14 +2078,15 @@
+@@ -2079,14 +2081,15 @@
ut_total_allocated_memory,
mem_pool_get_reserved(mem_comm_pool));
/* Calcurate reserved memories */
lock_sys_subtotal = 0;
if (trx_sys) {
-@@ -2109,10 +2112,10 @@
+@@ -2112,10 +2115,10 @@
" Recovery system %lu \t(%lu + %lu)\n",
(ulong) (btr_search_sys
+ rw_lock_x_lock(&buf_pool->page_hash_latch);
bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
-+ if (bpage) {
-+ block_mutex = buf_page_get_mutex_enter(bpage);
-+ ut_a(block_mutex);
-+ }
if (UNIV_LIKELY_NULL(bpage)) {
++
++ block_mutex = buf_page_get_mutex_enter(bpage);
++ ut_a(block_mutex);
++
if (!buf_pool_watch_is_sentinel(buf_pool, bpage)) {
/* The page was loaded meanwhile. */
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
ut_ad(buf_flush_ready_for_flush(bpage, flush_type));
buf_page_set_io_fix(bpage, BUF_IO_WRITE);
-@@ -1457,14 +1467,16 @@
+@@ -1455,14 +1465,16 @@
buf_pool = buf_pool_get(space, i);
if (srv_flush_neighbor_pages == 2) {
/* This is contiguous neighbor page flush and
-@@ -1482,11 +1494,9 @@
+@@ -1480,11 +1492,9 @@
if (flush_type != BUF_FLUSH_LRU
|| i == offset
|| buf_page_is_old(bpage)) {
&& (i == offset || !bpage->buf_fix_count)) {
/* We only try to flush those
neighbors != offset where the buf fix
-@@ -1502,11 +1512,12 @@
+@@ -1500,11 +1510,12 @@
ut_ad(!buf_pool_mutex_own(buf_pool));
count++;
continue;
+ //buf_pool_mutex_exit(buf_pool);
+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
- if (srv_flush_neigbor_pages == 2) {
+ if (srv_flush_neighbor_pages == 2) {
-@@ -1555,21 +1566,25 @@
+@@ -1553,21 +1564,25 @@
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
#endif /* UNIV_DEBUG */
/* These fields are protected by both the
buffer pool mutex and block mutex. */
-@@ -1585,13 +1600,18 @@
+@@ -1583,13 +1598,18 @@
*count,
n_to_flush);
return(flushed);
}
-@@ -1612,7 +1632,8 @@
+@@ -1610,7 +1630,8 @@
buf_page_t* bpage;
ulint count = 0;
do {
/* Start from the end of the list looking for a
-@@ -1634,7 +1655,8 @@
+@@ -1632,7 +1653,8 @@
should be flushed, we factor in this value. */
buf_lru_flush_page_count += count;
return(count);
}
-@@ -1662,9 +1684,10 @@
+@@ -1660,9 +1682,10 @@
{
ulint len;
buf_page_t* bpage;
/* If we have flushed enough, leave the loop */
do {
-@@ -1683,6 +1706,7 @@
+@@ -1681,6 +1704,7 @@
if (bpage) {
ut_a(bpage->oldest_modification > 0);
}
if (!bpage || bpage->oldest_modification >= lsn_limit) {
-@@ -1724,9 +1748,17 @@
+@@ -1722,9 +1746,17 @@
break;
}
buf_flush_list_mutex_exit(buf_pool);
-@@ -1735,7 +1767,7 @@
+@@ -1733,7 +1765,7 @@
} while (count < min_n && bpage != NULL && len > 0);
return(count);
}
-@@ -1774,13 +1806,15 @@
+@@ -1772,13 +1804,15 @@
|| sync_thread_levels_empty_except_dict());
#endif /* UNIV_SYNC_DEBUG */
break;
case BUF_FLUSH_LIST:
count = buf_flush_flush_list_batch(buf_pool, min_n, lsn_limit);
-@@ -1789,7 +1823,7 @@
+@@ -1787,7 +1821,7 @@
ut_error;
}
buf_flush_buffered_writes();
-@@ -2045,7 +2079,7 @@
+@@ -2059,7 +2093,7 @@
retry:
//buf_pool_mutex_enter(buf_pool);
if (have_LRU_mutex)
n_replaceable = UT_LIST_GET_LEN(buf_pool->free);
-@@ -2062,15 +2096,15 @@
+@@ -2076,15 +2110,15 @@
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
continue;
}
distance++;
-@@ -2079,7 +2113,7 @@
+@@ -2093,7 +2127,7 @@
//buf_pool_mutex_exit(buf_pool);
if (have_LRU_mutex)
if (n_replaceable >= BUF_FLUSH_FREE_BLOCK_MARGIN(buf_pool)) {
-@@ -2278,7 +2312,7 @@
+@@ -2292,7 +2326,7 @@
ut_ad(buf_flush_list_mutex_own(buf_pool));
ut_ad(ut_list_node_313->in_flush_list));
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
-@@ -2318,7 +2352,7 @@
+@@ -2332,7 +2366,7 @@
rnode = rbt_next(buf_pool->flush_rbt, rnode);
}
Otherwise, this is 0. */
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
-@@ -3102,7 +3102,7 @@
+@@ -3105,7 +3105,7 @@
level += log_sys->max_checkpoint_age
- (lsn - oldest_modification);
}
n_blocks++;
}
-@@ -3188,7 +3188,7 @@
+@@ -3191,7 +3191,7 @@
found = TRUE;
break;
}