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 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google 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
Google, Inc. Those modifications are gratefully acknowledged and are described
......@@ -3692,34 +3692,38 @@ btr_cur_update_in_place(
|| row_get_rec_trx_id(rec, index, offsets));
#ifdef BTR_CUR_HASH_ADAPT
if (block->index) {
/* TO DO: Can we skip this if none of the fields
index->search_info->curr_n_fields
are being updated? */
/* The function row_upd_changes_ord_field_binary works only
if the update vector was built for a clustered index, we must
NOT call it if index is secondary */
if (!dict_index_is_clust(index)
|| row_upd_changes_ord_field_binary(index, update, thr,
NULL, NULL)) {
/* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor);
{
rw_lock_t* ahi_latch = block->index
? btr_get_search_latch(block->index) : NULL;
if (ahi_latch) {
/* TO DO: Can we skip this if none of the fields
index->search_info->curr_n_fields
are being updated? */
/* The function row_upd_changes_ord_field_binary
does not work on a secondary index. */
if (!dict_index_is_clust(index)
|| row_upd_changes_ord_field_binary(
index, update, thr, NULL, NULL)) {
/* 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 */
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
if (block->index) {
btr_search_x_unlock(index);
if (ahi_latch) {
rw_lock_x_unlock(ahi_latch);
}
}
#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