Skip to content

Commit cedfe8e

Browse files
committed
MDEV-37250 buf_pool_t::shrink() assertion failure
buf_pool_t::shrink(): When relocating a dirty page of the temporary tablespace, reset the oldest_modification() on the discarded block, like we do for persistent pages in buf_flush_relocate_on_flush_list(). buf_pool_t::resize(): Add debug assertions to catch this error earlier. This bug does not seem to affect non-debug builds. Reviewed by: Thirunarayanan Balathandayuthapani
1 parent a8eeffb commit cedfe8e

File tree

4 files changed

+45
-1
lines changed

4 files changed

+45
-1
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
call mtr.add_suppression("innodb_buffer_pool_size change aborted");
2+
SET @b=REPEAT('0',1048576);
3+
CREATE TEMPORARY TABLE t (c MEDIUMTEXT) ENGINE=InnoDB;
4+
INSERT INTO t VALUES
5+
(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b);
6+
SET STATEMENT max_statement_time=0.000001 FOR
7+
SET GLOBAL innodb_buffer_pool_size=6291456;
8+
SET STATEMENT max_statement_time=0.000001 FOR
9+
SET GLOBAL innodb_buffer_pool_size=6291456;
10+
SET STATEMENT max_statement_time=0.000001 FOR
11+
SET GLOBAL innodb_buffer_pool_size=6291456;
12+
SET GLOBAL innodb_buffer_pool_size=6291456;
13+
SET GLOBAL innodb_buffer_pool_size=16777216;
14+
CHECKSUM TABLE t;
15+
Table Checksum
16+
test.t 4050893687
17+
DROP TEMPORARY TABLE t;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--innodb-buffer-pool-size=16m
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--source include/have_innodb.inc
2+
call mtr.add_suppression("innodb_buffer_pool_size change aborted");
3+
SET @b=REPEAT('0',1048576);
4+
CREATE TEMPORARY TABLE t (c MEDIUMTEXT) ENGINE=InnoDB;
5+
INSERT INTO t VALUES
6+
(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b),(@b);
7+
--error 0,ER_WRONG_USAGE
8+
SET STATEMENT max_statement_time=0.000001 FOR
9+
SET GLOBAL innodb_buffer_pool_size=6291456;
10+
--error 0,ER_WRONG_USAGE
11+
SET STATEMENT max_statement_time=0.000001 FOR
12+
SET GLOBAL innodb_buffer_pool_size=6291456;
13+
--error 0,ER_WRONG_USAGE
14+
SET STATEMENT max_statement_time=0.000001 FOR
15+
SET GLOBAL innodb_buffer_pool_size=6291456;
16+
--error 0,ER_WRONG_USAGE
17+
SET GLOBAL innodb_buffer_pool_size=6291456;
18+
SET GLOBAL innodb_buffer_pool_size=16777216;
19+
CHECKSUM TABLE t;
20+
DROP TEMPORARY TABLE t;

storage/innobase/buf/buf0buf.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,11 @@ ATTRIBUTE_COLD buf_pool_t::shrink_status buf_pool_t::shrink(size_t size)
17601760
buf_flush_relocate_on_flush_list(b, &block->page);
17611761
mysql_mutex_unlock(&flush_list_mutex);
17621762
}
1763+
else
1764+
{
1765+
ut_d(if (auto om= b->oldest_modification()) ut_ad(om == 2));
1766+
b->oldest_modification_.store(0, std::memory_order_relaxed);
1767+
}
17631768
}
17641769

17651770
/* relocate LRU list */
@@ -2091,10 +2096,11 @@ ATTRIBUTE_COLD void buf_pool_t::resize(size_t size, THD *thd) noexcept
20912096

20922097
while (buf_page_t *b= UT_LIST_GET_FIRST(withdrawn))
20932098
{
2099+
ut_ad(!b->oldest_modification());
2100+
ut_ad(b->state() == buf_page_t::NOT_USED);
20942101
UT_LIST_REMOVE(withdrawn, b);
20952102
UT_LIST_ADD_LAST(free, b);
20962103
ut_d(b->in_free_list= true);
2097-
ut_ad(b->state() == buf_page_t::NOT_USED);
20982104
b->lock.init();
20992105
}
21002106

0 commit comments

Comments
 (0)