From 1849dfef64d5f191c1fda3457ad97c6775f9a9f3 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 29 May 2024 13:10:15 +0530 Subject: [PATCH] MDEV-34256 InnoDB throws out of bound write due to temporary tablespace truncation - InnoDB fails with out of bound write error after temporary tablespace truncation. This issue caused by commit c507678b207a1a8ce6d99ea28fb947bed1d95795 (MDEV-28699). InnoDB fail to clear freed ranges if shrinking size is the last offset of the freed range. --- .../suite/innodb/r/temp_truncate_freed.result | 11 ++++++++ .../suite/innodb/t/temp_truncate_freed.test | 25 +++++++++++++++++++ storage/innobase/fsp/fsp0fsp.cc | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/innodb/r/temp_truncate_freed.result create mode 100644 mysql-test/suite/innodb/t/temp_truncate_freed.test diff --git a/mysql-test/suite/innodb/r/temp_truncate_freed.result b/mysql-test/suite/innodb/r/temp_truncate_freed.result new file mode 100644 index 00000000000..1ec26d6ada3 --- /dev/null +++ b/mysql-test/suite/innodb/r/temp_truncate_freed.result @@ -0,0 +1,11 @@ +set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size; +set @old_immediate_scrub_data_val= @@innodb_immediate_scrub_data_uncompressed; +SET GLOBAL innodb_immediate_scrub_data_uncompressed=1; +SET GLOBAL innodb_buffer_pool_size= 16777216; +CREATE TEMPORARY TABLE t1(c1 MEDIUMTEXT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (repeat(1,16777215)); +DROP TEMPORARY TABLE t1; +SET GLOBAL innodb_truncate_temporary_tablespace_now=1; +SET GLOBAL innodb_buffer_pool_size=10485760; +set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size; +set global innodb_immediate_scrub_data_uncompressed = @old_immediate_scrub_data_val; diff --git a/mysql-test/suite/innodb/t/temp_truncate_freed.test b/mysql-test/suite/innodb/t/temp_truncate_freed.test new file mode 100644 index 00000000000..d0a6b5fedf1 --- /dev/null +++ b/mysql-test/suite/innodb/t/temp_truncate_freed.test @@ -0,0 +1,25 @@ +--source include/have_innodb.inc + +set @old_innodb_buffer_pool_size = @@innodb_buffer_pool_size; +set @old_immediate_scrub_data_val= @@innodb_immediate_scrub_data_uncompressed; + +SET GLOBAL innodb_immediate_scrub_data_uncompressed=1; +SET GLOBAL innodb_buffer_pool_size= 16777216; + +CREATE TEMPORARY TABLE t1(c1 MEDIUMTEXT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (repeat(1,16777215)); +DROP TEMPORARY TABLE t1; +SET GLOBAL innodb_truncate_temporary_tablespace_now=1; + +let $wait_timeout = 180; +let $wait_condition = + SELECT SUBSTR(variable_value, 1, 30) = 'Completed resizing buffer pool' + FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_resize_status'; + +SET GLOBAL innodb_buffer_pool_size=10485760; +--source include/wait_condition.inc + +set global innodb_buffer_pool_size = @old_innodb_buffer_pool_size; +set global innodb_immediate_scrub_data_uncompressed = @old_immediate_scrub_data_val; +--source include/wait_condition.inc diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 1793ff44a2c..9555f0e6cfc 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -3714,7 +3714,7 @@ inline void fil_space_t::clear_freed_ranges(uint32_t threshold) { if (range.first >= threshold) continue; - else if (range.last > threshold) + else if (range.last >= threshold) { range_t new_range{range.first, threshold - 1}; current_ranges.add_range(new_range);