Skip to content

MDEV-36868: Inconsistency when shrinking innodb_buffer_pool_size #4062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions mysql-test/suite/innodb/r/innodb_buffer_pool_resize.result
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ SET STATEMENT foreign_key_checks=0, unique_checks=0 FOR
INSERT INTO t1 SELECT seq*4,seq*4 FROM seq_1_to_262144;
SET STATEMENT foreign_key_checks=0, unique_checks=0 FOR
INSERT INTO t2 SELECT seq*4,seq*4 FROM seq_1_to_16384;
SELECT @@GLOBAL.innodb_adaptive_hash_index;
@@GLOBAL.innodb_adaptive_hash_index
1
SET STATEMENT max_statement_time=1e-9 FOR
SET GLOBAL innodb_buffer_pool_size = 7340032;
SELECT @@GLOBAL.innodb_adaptive_hash_index;
@@GLOBAL.innodb_adaptive_hash_index
1
FOUND 1 /innodb_buffer_pool_size=7m.*resized from|innodb_buffer_pool_size change aborted/ in mysqld.1.err
set global innodb_buffer_pool_size = 7340032;
select count(val) from t1;
count(val)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ SET @save_limit=@@GLOBAL.innodb_limit_optimistic_insert_debug;
SET @save_size=@@GLOBAL.innodb_buffer_pool_size;
SET GLOBAL innodb_limit_optimistic_insert_debug=2;
SET GLOBAL innodb_buffer_pool_size=16777216;
call mtr.add_suppression("innodb_buffer_pool_size change aborted");
SET @old_innodb_adaptive_hash_index = @@innodb_adaptive_hash_index;
SET GLOBAL innodb_adaptive_hash_index = ON;
SET STATEMENT debug_dbug='+d,buf_shrink_fail' FOR
SET GLOBAL innodb_buffer_pool_size=8388608;
ERROR HY000: innodb_buffer_pool_size change aborted
SELECT @@GLOBAL.innodb_adaptive_hash_index,@@GLOBAL.innodb_buffer_pool_size;
@@GLOBAL.innodb_adaptive_hash_index @@GLOBAL.innodb_buffer_pool_size
1 16777216
SET GLOBAL innodb_adaptive_hash_index = @old_innodb_adaptive_hash_index;
CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 SELECT seq FROM seq_1_to_200;
SET GLOBAL innodb_max_purge_lag_wait=0;
Expand Down
12 changes: 12 additions & 0 deletions mysql-test/suite/innodb/t/innodb_buffer_pool_resize.test
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
--source include/not_embedded.inc # there are no messages in mysqld.1.err

--echo #
--echo # MDEV-29445: Reorganize buffer pool (and remove chunks)
Expand Down Expand Up @@ -42,6 +43,17 @@ INSERT INTO t2 SELECT seq*4,seq*4 FROM seq_1_to_16384;
SET GLOBAL innodb_read_only_compressed=@save_innodb_read_only_compressed;
--enable_query_log

SELECT @@GLOBAL.innodb_adaptive_hash_index;
--error 0,ER_WRONG_USAGE
SET STATEMENT max_statement_time=1e-9 FOR
SET GLOBAL innodb_buffer_pool_size = 7340032;
SELECT @@GLOBAL.innodb_adaptive_hash_index;

--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
--let SEARCH_PATTERN= InnoDB: Trying to shrink innodb_buffer_pool_size=7m
--let SEARCH_PATTERN= innodb_buffer_pool_size=7m.*resized from|innodb_buffer_pool_size change aborted
--source include/search_pattern_in_file.inc

# Attempt to shrink the buffer pool. This may occasionally fail.
--error 0,ER_WRONG_USAGE
set global innodb_buffer_pool_size = 7340032;
Expand Down
10 changes: 10 additions & 0 deletions mysql-test/suite/innodb/t/innodb_buffer_pool_resize_temporary.test
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ SET @save_size=@@GLOBAL.innodb_buffer_pool_size;
SET GLOBAL innodb_limit_optimistic_insert_debug=2;
SET GLOBAL innodb_buffer_pool_size=16777216;

call mtr.add_suppression("innodb_buffer_pool_size change aborted");

SET @old_innodb_adaptive_hash_index = @@innodb_adaptive_hash_index;
SET GLOBAL innodb_adaptive_hash_index = ON;
--error ER_WRONG_USAGE
SET STATEMENT debug_dbug='+d,buf_shrink_fail' FOR
SET GLOBAL innodb_buffer_pool_size=8388608;
SELECT @@GLOBAL.innodb_adaptive_hash_index,@@GLOBAL.innodb_buffer_pool_size;
SET GLOBAL innodb_adaptive_hash_index = @old_innodb_adaptive_hash_index;

CREATE TEMPORARY TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 SELECT seq FROM seq_1_to_200;

Expand Down
22 changes: 7 additions & 15 deletions storage/innobase/buf/buf0buf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,7 @@ ATTRIBUTE_COLD buf_pool_t::shrink_status buf_pool_t::shrink(size_t size)
noexcept
{
mysql_mutex_assert_owner(&mutex);
DBUG_EXECUTE_IF("buf_shrink_fail", return SHRINK_ABORT;);
buf_load_abort();

if (!n_blocks_to_withdraw)
Expand Down Expand Up @@ -2011,25 +2012,12 @@ ATTRIBUTE_COLD void buf_pool_t::resize(size_t size, THD *thd) noexcept
if (ahi_disabled)
btr_search_enable(true);
#endif
mysql_mutex_lock(&LOCK_global_system_variables);
bool resized= n_blocks_removed < 0;
if (n_blocks_removed > 0)
{
mysql_mutex_lock(&mutex);
resized= size_in_bytes == old_size;
if (resized)
{
size_in_bytes_requested= size;
size_in_bytes= size;
}
mysql_mutex_unlock(&mutex);
}

if (resized)
if (n_blocks_removed)
sql_print_information("InnoDB: innodb_buffer_pool_size=%zum (%zu pages)"
" resized from %zum (%zu pages)",
size >> 20, n_blocks_new, old_size >> 20,
old_blocks);
mysql_mutex_lock(&LOCK_global_system_variables);
}
else
{
Expand Down Expand Up @@ -2092,6 +2080,10 @@ ATTRIBUTE_COLD void buf_pool_t::resize(size_t size, THD *thd) noexcept
mysql_mutex_unlock(&mutex);
my_printf_error(ER_WRONG_USAGE, "innodb_buffer_pool_size change aborted",
MYF(ME_ERROR_LOG));
#ifdef BTR_CUR_HASH_ADAPT
if (ahi_disabled)
btr_search_enable(true);
#endif
Comment on lines +2083 to +2086
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a testcase to check it ? Looks like it is doable just checking checking innodb_adaptive_hash_index global which should reflect the correct state.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ebb0063 adds a nondeterministic test for this as well as for the message that the shrinking was aborted or completed. The buffer pool size change is not always being aborted in the test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we add a deterministic test for this one ? It should be as simple as checking if AHI is enabled after doing a buffer pool resize, right ?

Copy link
Contributor

@mariadb-DebarunBanerjee mariadb-DebarunBanerjee May 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is being exercised with a fairly good probability, close to 50%.
close to 50% in the optimized debug build

Marko mentions in slack that the non-deterministic case does hit the code sometimes. It would still be good to have one deterministic test covering the error exit path but I leave it to Marko.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked a few logs on buildbot.mariadb.org, the nondeterministic test never failed to shrink the buffer pool. So, I will add a deterministic debug-instrumented test as well.

mysql_mutex_lock(&LOCK_global_system_variables);
}

Expand Down