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

MDEV-14441 InnoDB hangs when setting innodb_adaptive_hash_index=OFF during UPDATE

This race condition is a regression caused by MDEV-12121.

btr_cur_update_in_place(): Determine block->index!=NULL only once
in order to determine whether an adaptive hash index bucket needs
to be exclusively locked and unlocked.

If we evaluated block->index multiple times, and the adaptive hash
index was disabled before we locked the adaptive hash index, then
we would never release the adaptive hash index bucket latch, which
would eventually lead to InnoDB hanging.
parent 9c6fc7b6
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc. Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2015, 2017, MariaDB Corporation. Copyright (c) 2015, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described Google, Inc. Those modifications are gratefully acknowledged and are described
...@@ -3692,34 +3692,38 @@ btr_cur_update_in_place( ...@@ -3692,34 +3692,38 @@ btr_cur_update_in_place(
|| row_get_rec_trx_id(rec, index, offsets)); || row_get_rec_trx_id(rec, index, offsets));
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
if (block->index) { {
/* TO DO: Can we skip this if none of the fields rw_lock_t* ahi_latch = block->index
index->search_info->curr_n_fields ? btr_get_search_latch(block->index) : NULL;
are being updated? */ if (ahi_latch) {
/* TO DO: Can we skip this if none of the fields
/* The function row_upd_changes_ord_field_binary works only index->search_info->curr_n_fields
if the update vector was built for a clustered index, we must are being updated? */
NOT call it if index is secondary */
/* The function row_upd_changes_ord_field_binary
if (!dict_index_is_clust(index) does not work on a secondary index. */
|| row_upd_changes_ord_field_binary(index, update, thr,
NULL, NULL)) { if (!dict_index_is_clust(index)
|| row_upd_changes_ord_field_binary(
/* Remove possible hash index pointer to this record */ index, update, thr, NULL, NULL)) {
btr_search_update_hash_on_delete(cursor);
/* Remove possible hash index pointer
to this record */
btr_search_update_hash_on_delete(cursor);
}
} }
btr_search_x_lock(index); rw_lock_x_lock(ahi_latch);
}
assert_block_ahi_valid(block); assert_block_ahi_valid(block);
#endif /* BTR_CUR_HASH_ADAPT */ #endif /* BTR_CUR_HASH_ADAPT */
row_upd_rec_in_place(rec, index, offsets, update, page_zip); row_upd_rec_in_place(rec, index, offsets, update, page_zip);
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
if (block->index) { if (ahi_latch) {
btr_search_x_unlock(index); rw_lock_x_unlock(ahi_latch);
}
} }
#endif /* BTR_CUR_HASH_ADAPT */ #endif /* BTR_CUR_HASH_ADAPT */
......
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