From f1deebbb0bcff9bd83c057c3164eefb345619a6f Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 14 Mar 2025 13:45:09 +0530 Subject: [PATCH] MDEV-35420 Server aborts while deleting the record in spatial index - This issue caused by commit a032f14b342c782b82dfcd9235805bee446e6fe8(MDEV-33559). In MDEV-33559, matched_rec::block was changed to pointer and assinged with the help of buf_block_alloc(). But patch fails to check for the block can be nullptr in rtr_check_discard_page(). rtr_cur_search_with_match(): Acquire rtr_match_mutex before creating shadow block for the matched records rtr_pcur_move_to_next(): Copy the shadow block to page cursor block under rtr_match_mutex --- mysql-test/suite/innodb_gis/r/rollback.result | 13 ++++++++++ mysql-test/suite/innodb_gis/t/rollback.test | 13 ++++++++++ storage/innobase/gis/gis0sea.cc | 26 +++++++++++++------ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb_gis/r/rollback.result b/mysql-test/suite/innodb_gis/r/rollback.result index 9e0db79667e..29d4f0884ba 100644 --- a/mysql-test/suite/innodb_gis/r/rollback.result +++ b/mysql-test/suite/innodb_gis/r/rollback.result @@ -412,3 +412,16 @@ update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3; ERROR HY000: Lost connection to MySQL server during query insert into t1 values(5, point(5,5), point(5,5), 5); drop table t1; +# +# MDEV-35420 Server aborts while deleting the record +# in spatial index +# +CREATE TABLE t1 (c POINT NOT NULL, SPATIAL(c)) engine=InnoDB; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +SET STATEMENT unique_checks=0,foreign_key_checks=0 FOR +START TRANSACTION; +INSERT INTO t1 SELECT ST_GeomFromText('POINT(114368751 656950466)') FROM seq_1_to_512; +ROLLBACK; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_gis/t/rollback.test b/mysql-test/suite/innodb_gis/t/rollback.test index a09986692ee..06fe6591a9a 100644 --- a/mysql-test/suite/innodb_gis/t/rollback.test +++ b/mysql-test/suite/innodb_gis/t/rollback.test @@ -8,6 +8,7 @@ # Avoid CrashReporter popup on Mac --source include/not_crashrep.inc --source include/have_innodb_16k.inc +--source include/have_sequence.inc CREATE TABLE t4 (id bigint(12) unsigned NOT NULL auto_increment, c2 varchar(15) collate utf8_bin default NULL, @@ -475,3 +476,15 @@ update t1 set a=point(5,5), b=point(5,5), c=5 where i < 3; insert into t1 values(5, point(5,5), point(5,5), 5); drop table t1; + +--echo # +--echo # MDEV-35420 Server aborts while deleting the record +--echo # in spatial index +--echo # +CREATE TABLE t1 (c POINT NOT NULL, SPATIAL(c)) engine=InnoDB; +CHECK TABLE t1; +SET STATEMENT unique_checks=0,foreign_key_checks=0 FOR +START TRANSACTION; +INSERT INTO t1 SELECT ST_GeomFromText('POINT(114368751 656950466)') FROM seq_1_to_512; +ROLLBACK; +DROP TABLE t1; diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index b9567ff03c3..66537a1ee11 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -495,10 +495,10 @@ rtr_pcur_move_to_next( rtr_rec_t rec; rec = rtr_info->matches->matched_recs->back(); rtr_info->matches->matched_recs->pop_back(); + cursor->btr_cur.page_cur.block = rtr_info->matches->block; mutex_exit(&rtr_info->matches->rtr_match_mutex); cursor->btr_cur.page_cur.rec = rec.r_rec; - cursor->btr_cur.page_cur.block = rtr_info->matches->block; DEBUG_SYNC_C("rtr_pcur_move_to_next_return"); return(true); @@ -1204,8 +1204,11 @@ rtr_check_discard_page( if (rtr_info->matches) { mutex_enter(&rtr_info->matches->rtr_match_mutex); - if (rtr_info->matches->block->page.id().page_no() - == pageno) { + /* matches->block could be nullptr when cursor + encounters empty table */ + if (rtr_info->matches->block + && rtr_info->matches->block->page.id().page_no() + == pageno) { if (!rtr_info->matches->matched_recs->empty()) { rtr_info->matches->matched_recs->clear(); } @@ -1849,6 +1852,15 @@ rtr_cur_search_with_match( ut_ad(orig_mode != PAGE_CUR_RTREE_LOCATE); + /* Collect matched records on page */ + offsets = rec_get_offsets( + rec, index, offsets, + index->n_fields, + ULINT_UNDEFINED, &heap); + + mutex_enter( + &rtr_info->matches->rtr_match_mutex); + if (!match_init) { rtr_init_match( rtr_info->matches, @@ -1856,14 +1868,12 @@ rtr_cur_search_with_match( match_init = true; } - /* Collect matched records on page */ - offsets = rec_get_offsets( - rec, index, offsets, - index->n_fields, - ULINT_UNDEFINED, &heap); rtr_leaf_push_match_rec( rec, rtr_info, offsets, page_is_comp(page)); + + mutex_exit( + &rtr_info->matches->rtr_match_mutex); } last_match_rec = rec;