Commit 7bccf3dd authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-28274 Assertion s <= READ_FIX failed in buf_page_t::set_state

buf_page_t::set_state(): Relax a debug assertion. It is fine to update
a read-fixed block descriptor to be both read-fixed and buffer-fixed.

buf_pool_t::watch_unset(): Fix some incorrect logic that was implemented
in commit e9e6db93.

Thanks to Elena Stepanova for the test case.
parent 5a4a3707
SET @buffering= @@innodb_change_buffering;
SET GLOBAL innodb_change_buffering= deletes;
SET @flush= @@innodb_flush_log_at_trx_commit;
SET GLOBAL innodb_flush_log_at_trx_commit= 0;
CREATE TABLE t1 (
a varchar(1024),
b varchar(1024),
c varchar(1024),
d varchar(1024),
e varchar(1024),
f varchar(1024),
g varchar(1024),
h varchar(1024),
key (a),
key (b),
key (c),
key (d)
) ENGINE=InnoDB;
INSERT INTO t1
SELECT REPEAT('x',10), REPEAT('x',13), REPEAT('x',427), REPEAT('x',244),
REPEAT('x',9), REPEAT('x',112), REPEAT('x',814), REPEAT('x',633)
FROM seq_1_to_1024;
CREATE TEMPORARY TABLE t2 (
a varchar(1024),
b varchar(1024),
c varchar(1024),
d varchar(1024),
e varchar(1024),
f varchar(1024),
g varchar(1024),
h varchar(1024),
i varchar(1024),
j varchar(1024),
k varchar(1024),
l varchar(1024),
m varchar(1024),
key (a),
key (b),
key (c),
key (d),
key (e),
key (f)
) ENGINE=InnoDB;
SET @x=REPEAT('x',512);
INSERT INTO t2 SELECT @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x
FROM seq_1_to_768;
DROP TABLE t1, t2;
SET GLOBAL innodb_change_buffering= @buffering;
SET GLOBAL innodb_flush_log_at_trx_commit= @flush;
--source include/have_innodb.inc
--source include/have_sequence.inc
SET @buffering= @@innodb_change_buffering;
SET GLOBAL innodb_change_buffering= deletes;
SET @flush= @@innodb_flush_log_at_trx_commit;
SET GLOBAL innodb_flush_log_at_trx_commit= 0;
CREATE TABLE t1 (
a varchar(1024),
b varchar(1024),
c varchar(1024),
d varchar(1024),
e varchar(1024),
f varchar(1024),
g varchar(1024),
h varchar(1024),
key (a),
key (b),
key (c),
key (d)
) ENGINE=InnoDB;
INSERT INTO t1
SELECT REPEAT('x',10), REPEAT('x',13), REPEAT('x',427), REPEAT('x',244),
REPEAT('x',9), REPEAT('x',112), REPEAT('x',814), REPEAT('x',633)
FROM seq_1_to_1024;
CREATE TEMPORARY TABLE t2 (
a varchar(1024),
b varchar(1024),
c varchar(1024),
d varchar(1024),
e varchar(1024),
f varchar(1024),
g varchar(1024),
h varchar(1024),
i varchar(1024),
j varchar(1024),
k varchar(1024),
l varchar(1024),
m varchar(1024),
key (a),
key (b),
key (c),
key (d),
key (e),
key (f)
) ENGINE=InnoDB;
SET @x=REPEAT('x',512);
INSERT INTO t2 SELECT @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x, @x
FROM seq_1_to_768;
--disable_query_log
--let $run=1024
while ($run)
{
eval DELETE FROM t1 LIMIT 1 /* $run */;
--dec $run
}
--enable_query_log
# Cleanup
DROP TABLE t1, t2;
SET GLOBAL innodb_change_buffering= @buffering;
SET GLOBAL innodb_flush_log_at_trx_commit= @flush;
......@@ -2146,15 +2146,17 @@ void buf_pool_t::watch_unset(const page_id_t id, buf_pool_t::hash_chain &chain)
if (!watch_is_sentinel(*w))
{
no_watch:
ut_d(const auto s=) w->unfix();
ut_ad(~buf_page_t::LRU_MASK & s);
w->unfix();
w= nullptr;
}
const auto state= w->state();
ut_ad(~buf_page_t::LRU_MASK & state);
ut_ad(state >= buf_page_t::UNFIXED);
if (state != buf_page_t::UNFIXED + 1)
goto no_watch;
else
{
const auto state= w->state();
ut_ad(~buf_page_t::LRU_MASK & state);
ut_ad(state >= buf_page_t::UNFIXED + 1);
if (state != buf_page_t::UNFIXED + 1)
goto no_watch;
}
}
if (!w)
......
......@@ -2009,7 +2009,8 @@ inline void buf_page_t::set_state(uint32_t s)
{
mysql_mutex_assert_owner(&buf_pool.mutex);
ut_ad(s <= REMOVE_HASH || s >= UNFIXED);
ut_ad(s <= READ_FIX);
ut_ad(s < WRITE_FIX);
ut_ad(s <= READ_FIX || zip.fix == READ_FIX);
zip.fix= s;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment