Commit 3d901438 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-31559 btr_search_hash_table_validate() does not check if CHECK TABLE is killed

btr_search_hash_table_validate(), btr_search_validate(): Add the
parameter THD for checking if the statement has been killed.
Any non-QUICK CHECK TABLE will validate the entire adaptive hash index
for all InnoDB tables, which may be extremely slow when running
multiple concurrent CHECK TABLE.
parent 6d911219
...@@ -2116,14 +2116,13 @@ static bool ha_validate(const hash_table_t *table, ...@@ -2116,14 +2116,13 @@ static bool ha_validate(const hash_table_t *table,
} }
/** Validates the search system for given hash table. /** Validates the search system for given hash table.
@param[in] hash_table_id hash table to validate @param thd connection, for checking if CHECK TABLE has been killed
@return TRUE if ok */ @param hash_table_id hash table to validate
static @return true if ok */
ibool static bool btr_search_hash_table_validate(THD *thd, ulint hash_table_id)
btr_search_hash_table_validate(ulint hash_table_id)
{ {
ha_node_t* node; ha_node_t* node;
ibool ok = TRUE; bool ok = true;
ulint i; ulint i;
ulint cell_count; ulint cell_count;
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
...@@ -2131,9 +2130,15 @@ btr_search_hash_table_validate(ulint hash_table_id) ...@@ -2131,9 +2130,15 @@ btr_search_hash_table_validate(ulint hash_table_id)
rec_offs* offsets = offsets_; rec_offs* offsets = offsets_;
btr_search_x_lock_all(); btr_search_x_lock_all();
if (!btr_search_enabled) { if (!btr_search_enabled || (thd && thd_kill_level(thd))) {
func_exit:
btr_search_x_unlock_all(); btr_search_x_unlock_all();
return(TRUE);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return ok;
} }
/* How many cells to check before temporarily releasing /* How many cells to check before temporarily releasing
...@@ -2160,8 +2165,8 @@ btr_search_hash_table_validate(ulint hash_table_id) ...@@ -2160,8 +2165,8 @@ btr_search_hash_table_validate(ulint hash_table_id)
btr_search_x_lock_all(); btr_search_x_lock_all();
if (!btr_search_enabled) { if (!btr_search_enabled
ok = true; || (thd && thd_kill_level(thd))) {
goto func_exit; goto func_exit;
} }
...@@ -2268,8 +2273,8 @@ btr_search_hash_table_validate(ulint hash_table_id) ...@@ -2268,8 +2273,8 @@ btr_search_hash_table_validate(ulint hash_table_id)
btr_search_x_lock_all(); btr_search_x_lock_all();
if (!btr_search_enabled) { if (!btr_search_enabled
ok = true; || (thd && thd_kill_level(thd))) {
goto func_exit; goto func_exit;
} }
...@@ -2290,33 +2295,23 @@ btr_search_hash_table_validate(ulint hash_table_id) ...@@ -2290,33 +2295,23 @@ btr_search_hash_table_validate(ulint hash_table_id)
ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1); ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1);
if (!ha_validate(&part.table, i, end_index)) { if (!ha_validate(&part.table, i, end_index)) {
ok = FALSE; ok = false;
} }
} }
mysql_mutex_unlock(&buf_pool.mutex); mysql_mutex_unlock(&buf_pool.mutex);
func_exit: goto func_exit;
btr_search_x_unlock_all();
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(ok);
} }
/** Validate the search system. /** Validates the search system.
@return true if ok. */ @param thd connection, for checking if CHECK TABLE has been killed
bool @return true if ok */
btr_search_validate() bool btr_search_validate(THD *thd)
{ {
for (ulint i = 0; i < btr_ahi_parts; ++i) { for (ulint i= 0; i < btr_ahi_parts; ++i)
if (!btr_search_hash_table_validate(i)) { if (!btr_search_hash_table_validate(thd, i))
return(false); return(false);
} return true;
}
return(true);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
......
...@@ -15406,7 +15406,8 @@ ha_innobase::check( ...@@ -15406,7 +15406,8 @@ ha_innobase::check(
/* We validate the whole adaptive hash index for all tables /* We validate the whole adaptive hash index for all tables
at every CHECK TABLE only when QUICK flag is not present. */ at every CHECK TABLE only when QUICK flag is not present. */
if (!(check_opt->flags & T_QUICK) && !btr_search_validate()) { if (!(check_opt->flags & T_QUICK)
&& !btr_search_validate(m_prebuilt->trx->mysql_thd)) {
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
ER_NOT_KEYFILE, ER_NOT_KEYFILE,
"InnoDB: The adaptive hash index is corrupted."); "InnoDB: The adaptive hash index is corrupted.");
......
...@@ -127,8 +127,9 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor, ...@@ -127,8 +127,9 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
void btr_search_update_hash_on_delete(btr_cur_t *cursor); void btr_search_update_hash_on_delete(btr_cur_t *cursor);
/** Validates the search system. /** Validates the search system.
@param thd connection, for checking if CHECK TABLE has been killed
@return true if ok */ @return true if ok */
bool btr_search_validate(); bool btr_search_validate(THD *thd);
/** Lock all search latches in exclusive mode. */ /** Lock all search latches in exclusive mode. */
static inline void btr_search_x_lock_all(); static inline void btr_search_x_lock_all();
......
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