diff --git a/btr/btr0sea.c b/btr/btr0sea.c index 32e22aa51bc..937883b58e1 100644 --- a/btr/btr0sea.c +++ b/btr/btr0sea.c @@ -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); - for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) { + 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); + } + node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; while (node != NULL) { @@ -1660,10 +1675,21 @@ btr_search_validate(void) node = node->next; } } - - if (!ha_validate(btr_search_sys->hash_index)) { - ok = FALSE; + 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); diff --git a/ha/ha0ha.c b/ha/ha0ha.c index fdc3d48c14b..29616885518 100644 --- a/ha/ha0ha.c +++ b/ha/ha0ha.c @@ -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 */ + /* out: TRUE if ok */ + 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); diff --git a/include/ha0ha.h b/include/ha0ha.h index 60ccb0be5d5..b0f4fa83892 100644 --- a/include/ha0ha.h +++ b/include/ha0ha.h @@ -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 */ + /* out: TRUE if ok */ + 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. */