diff --git a/mysql-test/suite/innodb/r/ibuf_delete.result b/mysql-test/suite/innodb/r/ibuf_delete.result new file mode 100644 index 00000000000..1481fca9bf6 --- /dev/null +++ b/mysql-test/suite/innodb/r/ibuf_delete.result @@ -0,0 +1,49 @@ +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; diff --git a/mysql-test/suite/innodb/t/ibuf_delete.test b/mysql-test/suite/innodb/t/ibuf_delete.test new file mode 100644 index 00000000000..82b740b6aa1 --- /dev/null +++ b/mysql-test/suite/innodb/t/ibuf_delete.test @@ -0,0 +1,67 @@ +--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; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index b948fefe55a..1bdbf134249 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -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) diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 7c372379ad3..9e341546c6a 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -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; }