mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 03:47:17 +02:00
MDEV-21512 InnoDB may hang due to SPATIAL INDEX
MySQL 5.7.29 includes the following fix: Bug #30287668 INNODB: A LONG SEMAPHORE WAIT mysql/mysql-server@5cdbb22b51 There is no test case. It seems that the problem could occur when a spatial index is large and peculiar enough so that multiple R-tree leaf pages will have the exactly same maximum bounding rectangle (MBR). The commit message suggests that the hang can occur when R-tree non-leaf pages are being merged, which should only be possible during transaction rollback or the purge of transaction history, when the R-tree index is at least 2 levels high and very many records are being deleted. The message says that a comparison result that two spatial index node pointer records are equal will cause an infinite loop in rtr_page_copy_rec_list_end_no_locks(). Hence, we must include the child page number in the comparison to be consistent with mysql/mysql-server@2e11fe0e15. We fix this bug in a simpler way, involving fewer code changes. cmp_rec_rec(): Renamed from cmp_rec_rec_with_match(). Assert that rec2 always resides in an index page. Treat non-leaf spatial index pages specially.
This commit is contained in:
parent
c3695b4058
commit
457ce97ef2
6 changed files with 87 additions and 138 deletions
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2019, MariaDB Corporation.
|
||||
Copyright (c) 2019, 2020, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -1449,10 +1449,9 @@ rtr_page_copy_rec_list_end_no_locks(
|
|||
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
|
||||
is_leaf,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
cmp = cmp_rec_rec_with_match(cur1_rec, cur_rec,
|
||||
offsets1, offsets2,
|
||||
index, FALSE,
|
||||
&cur_matched_fields);
|
||||
cmp = cmp_rec_rec(cur1_rec, cur_rec,
|
||||
offsets1, offsets2, index, false,
|
||||
&cur_matched_fields);
|
||||
if (cmp < 0) {
|
||||
page_cur_move_to_prev(&page_cur);
|
||||
break;
|
||||
|
|
@ -1564,15 +1563,13 @@ rtr_page_copy_rec_list_start_no_locks(
|
|||
|
||||
while (!page_rec_is_supremum(cur_rec)) {
|
||||
ulint cur_matched_fields = 0;
|
||||
int cmp;
|
||||
|
||||
offsets2 = rec_get_offsets(cur_rec, index, offsets2,
|
||||
is_leaf,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
cmp = cmp_rec_rec_with_match(cur1_rec, cur_rec,
|
||||
offsets1, offsets2,
|
||||
index, FALSE,
|
||||
&cur_matched_fields);
|
||||
int cmp = cmp_rec_rec(cur1_rec, cur_rec,
|
||||
offsets1, offsets2, index, false,
|
||||
&cur_matched_fields);
|
||||
if (cmp < 0) {
|
||||
page_cur_move_to_prev(&page_cur);
|
||||
cur_rec = page_cur_get_rec(&page_cur);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue