Commit 6aab3916 authored by marko's avatar marko

branches/zip: Make innodb_adaptive_hash_index settable.

btr_search_disabled: Rename to btr_search_enabled and change the type
to char, so that it can be directly linked to the MySQL parameters.
Note that the variable is protected by btr_search_latch and
btr_search_enabled_mutex, a new mutex introduced in this patch.

btr_search_enabled_mutex: A new mutex, to protect btr_search_enabled
together with btr_search_latch.

buf_pool_drop_hash_index(): New function, to be called from
btr_search_disable().

btr_search_disable(), btr_search_enable(): Fix bugs.  These functions
were previously unused.

btr_search_guess_on_hash(), btr_search_build_page_hash_index():
Check btr_search_enabled once more, while holding btr_search_latch.

btr_cur_search_to_nth_level(): Note that the reads of btr_search_enabled
may be dirty and explain why it should not be a problem.

innobase_adaptive_hash_index: Remove. The variable btr_search_enabled will be used directly instead.

innodb_adaptive_hash_index_update(): New function, an update callback for
innodb_adaptive_hash_index.  This will call either btr_search_disable()
or btr_search_enable() when the value is assigned.  The functions will
be called even if the value does not appear to be changed, e.g., when
setting from TRUE to TRUE or FALSE to FALSE.

rb://85 approved by Heikki Tuuri.  This addresses Issue #163.
parent 635268b7
......@@ -371,7 +371,10 @@ btr_cur_search_to_nth_level(
#ifdef PAGE_CUR_LE_OR_EXTENDS
&& mode != PAGE_CUR_LE_OR_EXTENDS
#endif /* PAGE_CUR_LE_OR_EXTENDS */
&& !UNIV_UNLIKELY(btr_search_disabled)
/* If !has_search_latch, we do a dirty read of
btr_search_enabled below, and btr_search_guess_on_hash()
will have to check it again. */
&& UNIV_LIKELY(btr_search_enabled)
&& btr_search_guess_on_hash(index, info, tuple, mode,
latch_mode, cursor,
has_search_latch, mtr)) {
......@@ -608,7 +611,11 @@ retry_page_get:
cursor->up_bytes = up_bytes;
#ifdef BTR_CUR_ADAPT
if (!UNIV_UNLIKELY(btr_search_disabled)) {
/* We do a dirty read of btr_search_enabled here. We
will properly check btr_search_enabled again in
btr_search_build_page_hash_index() before building a
page hash index, while holding btr_search_latch. */
if (UNIV_LIKELY(btr_search_enabled)) {
btr_search_info_update(index, cursor);
}
......
......@@ -19,8 +19,11 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0btr.h"
#include "ha0ha.h"
/* Flag: has the search system been disabled? */
UNIV_INTERN ibool btr_search_disabled = FALSE;
/* Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
UNIV_INTERN char btr_search_enabled = TRUE;
static mutex_t btr_search_enabled_mutex;
/* A dummy variable to fool the compiler */
UNIV_INTERN ulint btr_search_this_is_zero = 0;
......@@ -139,11 +142,11 @@ 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));
btr_search_sys->hash_index = ha_create(hash_size, 0, 0);
}
/************************************************************************
......@@ -153,12 +156,20 @@ void
btr_search_disable(void)
/*====================*/
{
btr_search_disabled = TRUE;
mutex_enter(&btr_search_enabled_mutex);
rw_lock_x_lock(&btr_search_latch);
ha_clear(btr_search_sys->hash_index);
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();
/* btr_search_enabled_mutex should guarantee this. */
ut_ad(!btr_search_enabled);
rw_lock_x_unlock(&btr_search_latch);
mutex_exit(&btr_search_enabled_mutex);
}
/************************************************************************
......@@ -168,7 +179,13 @@ void
btr_search_enable(void)
/*====================*/
{
btr_search_disabled = FALSE;
mutex_enter(&btr_search_enabled_mutex);
rw_lock_x_lock(&btr_search_latch);
btr_search_enabled = TRUE;
rw_lock_x_unlock(&btr_search_latch);
mutex_exit(&btr_search_enabled_mutex);
}
/*********************************************************************
......@@ -797,6 +814,10 @@ btr_search_guess_on_hash(
if (UNIV_LIKELY(!has_search_latch)) {
rw_lock_s_lock(&btr_search_latch);
if (UNIV_UNLIKELY(!btr_search_enabled)) {
goto failure_unlock;
}
}
ut_ad(btr_search_latch.writer != RW_LOCK_EX);
......@@ -1301,6 +1322,10 @@ btr_search_build_page_hash_index(
rw_lock_x_lock(&btr_search_latch);
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))) {
......
......@@ -998,6 +998,88 @@ buf_pool_free(void)
buf_pool->n_chunks = 0;
}
/************************************************************************
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. */
UNIV_INTERN
void
buf_pool_drop_hash_index(void)
/*==========================*/
{
ibool released_search_latch;
#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;
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 */
if (!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);
}
}
} while (released_search_latch);
}
/************************************************************************
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
......
......@@ -167,7 +167,6 @@ static my_bool innobase_locks_unsafe_for_binlog = FALSE;
static my_bool innobase_rollback_on_timeout = FALSE;
static my_bool innobase_create_status_file = FALSE;
static my_bool innobase_stats_on_metadata = TRUE;
static my_bool innobase_adaptive_hash_index = TRUE;
static char* internal_innobase_data_file_path = NULL;
......@@ -2117,8 +2116,6 @@ innobase_init(
srv_max_n_open_files = (ulint) innobase_open_files;
srv_innodb_status = (ibool) innobase_create_status_file;
btr_search_disabled = (ibool) !innobase_adaptive_hash_index;
srv_print_verbose_log = mysqld_embedded ? 0 : 1;
/* Store the default charset-collation number of this MySQL
......@@ -9362,6 +9359,28 @@ innodb_file_format_check_update(
}
}
/********************************************************************
Update the system variable innodb_adaptive_hash_index using the "saved"
value. This function is registered as a callback with MySQL. */
static
void
innodb_adaptive_hash_index_update(
/*==============================*/
THD* thd, /* in: thread handle */
struct st_mysql_sys_var* var, /* in: pointer to
system variable */
void* var_ptr, /* out: where the
formal string goes */
const void* save) /* in: immediate result
from check function */
{
if (*(my_bool*) save) {
btr_search_enable();
} else {
btr_search_disable();
}
}
/*****************************************************************
Check if it is a valid value of innodb_change_buffering. This function is
registered as a callback with MySQL. */
......@@ -9552,11 +9571,11 @@ static MYSQL_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
"The number of index pages to sample when calculating statistics (default 8)",
NULL, NULL, 8, 1, ~0ULL, 0);
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, btr_search_enabled,
PLUGIN_VAR_OPCMDARG,
"Enable InnoDB adaptive hash index (enabled by default). "
"Disable with --skip-innodb-adaptive-hash-index.",
NULL, NULL, TRUE);
NULL, innodb_adaptive_hash_index_update, TRUE);
static MYSQL_SYSVAR_ULONG(replication_delay, srv_replication_delay,
PLUGIN_VAR_RQCMDARG,
......
......@@ -165,8 +165,9 @@ btr_search_validate(void);
/*======================*/
/* out: TRUE if ok */
/* Flag: has the search system been disabled? */
extern ibool btr_search_disabled;
/* Flag: has the search system been enabled?
Protected by btr_search_latch and btr_search_enabled_mutex. */
extern char btr_search_enabled;
/* The search info struct in an index */
......
......@@ -92,6 +92,15 @@ void
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. */
UNIV_INTERN
void
buf_pool_drop_hash_index(void);
/*==========================*/
/************************************************************************
Relocate a buffer control block. Relocates the block on the LRU list
and in buf_pool->page_hash. Does not relocate bpage->list.
......
......@@ -433,7 +433,8 @@ or row lock! */
#define SYNC_TRX_SYS_HEADER 290
#define SYNC_LOG 170
#define SYNC_RECV 168
#define SYNC_WORK_QUEUE 161
#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
......
......@@ -1059,6 +1059,7 @@ 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:
......
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