Commit 3d98fd8b authored by osku's avatar osku

Port r172 from branches/5.0:

Fix bug #17126, CHECK TABLE blocking other queries, by releasing the
btr_search_latch periodically during the adaptive hash table validation.
parent 4a6b2c70
......@@ -1600,14 +1600,29 @@ btr_search_validate(void)
ulint n_page_dumps = 0;
ibool ok = TRUE;
ulint i;
ulint cell_count;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
/* How many cells to check before temporarily releasing
btr_search_latch. */
ulint chunk_size = 10000;
rw_lock_x_lock(&btr_search_latch);
cell_count = hash_get_n_cells(btr_search_sys->hash_index);
for (i = 0; i < cell_count; i++) {
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) {
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
while (node != NULL) {
......@@ -1661,10 +1676,21 @@ btr_search_validate(void)
}
}
if (!ha_validate(btr_search_sys->hash_index)) {
for (i = 0; i < cell_count; i += chunk_size) {
ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1);
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if (i != 0) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
ok = FALSE;
}
}
rw_lock_x_unlock(&btr_search_latch);
if (UNIV_LIKELY_NULL(heap)) {
......
......@@ -281,20 +281,26 @@ ha_remove_all_nodes_to_page(
}
/*****************************************************************
Validates a hash table. */
Validates a given range of the cells in hash table. */
ibool
ha_validate(
/*========*/
/* out: TRUE if ok */
hash_table_t* table) /* in: hash table */
hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index) /* in: end index */
{
hash_cell_t* cell;
ha_node_t* node;
ibool ok = TRUE;
ulint i;
for (i = 0; i < hash_get_n_cells(table); i++) {
ut_a(start_index <= end_index);
ut_a(start_index < hash_get_n_cells(table));
ut_a(end_index < hash_get_n_cells(table));
for (i = start_index; i <= end_index; i++) {
cell = hash_get_nth_cell(table, i);
......
......@@ -99,13 +99,15 @@ ha_remove_all_nodes_to_page(
ulint fold, /* in: fold value */
page_t* page); /* in: buffer page */
/*****************************************************************
Validates a hash table. */
Validates a given range of the cells in hash table. */
ibool
ha_validate(
/*========*/
/* out: TRUE if ok */
hash_table_t* table); /* in: hash table */
hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index); /* in: end index */
/*****************************************************************
Prints info of a hash table. */
......
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