diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2023-03-16 15:52:42 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2023-03-16 15:52:42 +0200 |
commit | f2096478d5750b983f9a9cc4691d20e152dafd4a (patch) | |
tree | 0550b7949b594b7b045f67bf8a754ffdb5874562 /storage/innobase/include | |
parent | 85cbfaefee694cdd490b357444f24ff16b8042e8 (diff) | |
download | mariadb-git-f2096478d5750b983f9a9cc4691d20e152dafd4a.tar.gz |
MDEV-29835 InnoDB hang on B-tree split or merge
This is a follow-up to
commit de4030e4d49805a7ded5c0bfee01cc3fd7623522 (MDEV-30400),
which fixed some hangs related to B-tree split or merge.
btr_root_block_get(): Use and update the root page guess. This is just
a minor performance optimization, not affecting correctness.
btr_validate_level(): Remove the parameter "lockout", and always
acquire an exclusive dict_index_t::lock in CHECK TABLE without QUICK.
This is needed in order to avoid latching order violation in
btr_page_get_father_node_ptr_for_validate().
btr_cur_need_opposite_intention(): Return true in case
btr_cur_compress_recommendation() would hold later during the
mini-transaction, or if a page underflow or overflow is possible.
If we return true, our caller will escalate to aqcuiring an exclusive
dict_index_t::lock, to prevent a latching order violation and deadlock
during btr_compress() or btr_page_split_and_insert().
btr_cur_t::search_leaf(), btr_cur_t::open_leaf():
Also invoke btr_cur_need_opposite_intention() on the leaf page.
btr_cur_t::open_leaf(): When escalating to exclusive index locking,
acquire exclusive latches on all pages as well.
innobase_instant_try(): Return an error code if the root page cannot
be retrieved.
In addition to the normal stress testing with Random Query Generator (RQG)
this has been tested with
./mtr --mysqld=--loose-innodb-limit-optimistic-insert-debug=2
but with the injection in btr_cur_optimistic_insert() for non-leaf pages
adjusted so that it would use the value 3. (Otherwise, infinite page
splits could occur in some mtr tests.)
Tested by: Matthias Leich
Diffstat (limited to 'storage/innobase/include')
-rw-r--r-- | storage/innobase/include/btr0btr.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/btr0types.h | 3 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 3 |
3 files changed, 7 insertions, 1 deletions
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index a1cc10b05db..a56598d3620 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -445,7 +445,7 @@ Gets the root node of a tree and x- or s-latches it. buf_block_t* btr_root_block_get( /*===============*/ - const dict_index_t* index, /*!< in: index tree */ + dict_index_t* index, /*!< in: index tree */ rw_lock_type_t mode, /*!< in: either RW_S_LATCH or RW_X_LATCH */ mtr_t* mtr, /*!< in: mtr */ diff --git a/storage/innobase/include/btr0types.h b/storage/innobase/include/btr0types.h index 912c022c64f..fc829e7857a 100644 --- a/storage/innobase/include/btr0types.h +++ b/storage/innobase/include/btr0types.h @@ -103,6 +103,9 @@ enum btr_latch_mode { dict_index_t::lock is being held in non-exclusive mode. */ BTR_MODIFY_LEAF_ALREADY_LATCHED = BTR_MODIFY_LEAF | BTR_ALREADY_S_LATCHED, + /** Attempt to modify records in an x-latched tree. */ + BTR_MODIFY_TREE_ALREADY_LATCHED = BTR_MODIFY_TREE + | BTR_ALREADY_S_LATCHED, /** U-latch root and X-latch a leaf page, assuming that dict_index_t::lock is being held in U mode. */ BTR_MODIFY_ROOT_AND_LEAF_ALREADY_LATCHED = BTR_MODIFY_ROOT_AND_LEAF diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index f3fe1841b2e..60e01abe18d 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -344,6 +344,9 @@ public: /** Upgrade U locks on a block to X */ void page_lock_upgrade(const buf_block_t &block); + /** Upgrade index U lock to X */ + ATTRIBUTE_COLD void index_lock_upgrade(); + /** Check if we are holding tablespace latch @param space tablespace to search for @return whether space.latch is being held */ |