Bug #117436 | PCursor::move_to_next_block may skip records incorrectly | ||
---|---|---|---|
Submitted: | 11 Feb 7:22 | Modified: | 16 Apr 4:03 |
Reporter: | Ruyi Zhang (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
Version: | 8.0 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | Contribution, cursor parallel-scan |
[11 Feb 7:22]
Ruyi Zhang
[11 Feb 12:21]
MySQL Verification Team
Hi Mr. Zhang, Thank you for your bug report. We have analysed your report closely. We agree with your findings. This is now a bug verified by code analysis.
[12 Feb 3:46]
Ruyi Zhang
Later, we wrote an MTR to confirm this issue: We modified the `Parallel_reader::add_scan` so that it always generates only one range. This will facilitate us to reproduce the issue in scenarios where the height of the BTREE is relatively low. After record 9 is deleted, the records in leaf 6 will be merged to the left into leaf 7, and leaf 6 will be reclaimed. `restore_to_first_unprocessed` fails to properly handle the records merged during the `SMO`, resulting in the loss of these records during the scan. ``` diff --git a/mysql-test/suite/innodb/t/parallel_scan_miss_rec.test b/mysql-test/suite/innodb/t/parallel_scan_miss_rec.test index e69de29bb2d..6b0d12bbe53 100644 --- a/mysql-test/suite/innodb/t/parallel_scan_miss_rec.test +++ b/mysql-test/suite/innodb/t/parallel_scan_miss_rec.test @@ -0,0 +1,50 @@ +# after insert 1,2,3,7,8,10 +# root(4) +# leaf(5)[1,2] - leaf(6)[3,7,8,10] + +# after insert 9 +# root(4) +# leaf(5)[1,2] - leaf(7)[3,7] - leaf(6)[8,9,10] + +# after delete 9 +# +# leaf(5)[1,2] - leaf(7)[3,7,8,10] + +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--connect(con1, localhost, root,,) + +--connection default +create table page_test(id int primary key, val varchar(3300)); + +insert into page_test values (1, repeat('a', 3300)); +insert into page_test values (2, repeat('a', 3300)); +insert into page_test values (3, repeat('a', 3300)); +insert into page_test values (7, repeat('a', 3300)); +insert into page_test values (8, repeat('a', 3300)); +insert into page_test values (10, repeat('a', 3300)); + +SET GLOBAL innodb_purge_stop_now = ON; +insert into page_test values (9, repeat('a', 3300)); +delete from page_test where id=9; + +--connection con1 +set global debug="+d,pcursor_move_to_next_block_release_latches"; +set DEBUG_SYNC="pcursor_move_to_next_block_latches_released SIGNAL latches_released WAIT_FOR continue EXECUTE 2"; +send ALTER TABLE page_test ENGINE=InnoDB, ALGORITHM=INPLACE; +--connection default +set DEBUG_SYNC="now WAIT_FOR latches_released"; +set DEBUG_SYNC="now SIGNAL continue"; + +set DEBUG_SYNC="now WAIT_FOR latches_released"; +SET GLOBAL innodb_purge_run_now = ON; +--source include/wait_innodb_all_purged.inc +set DEBUG_SYNC="now SIGNAL continue"; + +--connection con1 +reap; +--connection default +set global debug="-d,pcursor_move_to_next_block_release_latches"; +select id from page_test; +drop table page_test; \ No newline at end of file diff --git a/storage/innobase/row/row0pread.cc b/storage/innobase/row/row0pread.cc index 46e1075763e..c471a866c0d 100644 --- a/storage/innobase/row/row0pread.cc +++ b/storage/innobase/row/row0pread.cc @@ -1549,6 +1549,11 @@ dberr_t Parallel_reader::add_scan(trx_t *trx, return (err); } + if (ranges.size() > 0) { + ranges.erase(ranges.begin() + 1, ranges.end()); + ranges.back().second = std::make_shared<Parallel_reader::Scan_ctx::Iter>(); + } + err = scan_ctx->create_contexts(ranges); scan_ctx->index_s_unlock(); ``` After the MTR runs the INPLACE DDL, records 8 and 10 will be missing from the new table.
[12 Feb 13:58]
MySQL Verification Team
Thank you, Mr. Zhang.
[16 Apr 4:03]
Ruyi Zhang
Hello, we noticed that there are relevant improvements in version 8.0.42 at https://github.com/mysql/mysql-server/commit/d2c1214b45ac1efc70dcd27bfcb737e3bed09a06, but we can still observe this error in version 8.0.42.
[29 Apr 9:50]
Dmitry Lenev
Hello! Here is a straightforward patch which seems to fix this issue, which we are contributing. The patch is against MySQL 8.0.42 tree. Thanks a lot to Bytedance team for coming up with such a great test case!
[29 Apr 9:51]
Dmitry Lenev
Straightforward fix for bug#117436 and a test case. (*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.
Contribution: ps-9703-bug117436-contrib.patch (text/x-patch), 17.02 KiB.
[29 Apr 10:27]
MySQL Verification Team
Thank you, Dmitry for the Contribution. regards, Umesh