MDEV-26784 [Warning] InnoDB: Difficult to find free blocks in the buffer pool

Problem:
=======
  InnoDB ran out of memory during recovery and it fails to
flush the dirty LRU blocks. The reason is that buffer pool
can ran out before the LRU list length reaches
BUF_LRU_OLD_MIN_LEN(256) threshold.

Fix:
====
During recovery, InnoDB should write out and evict all
dirty blocks.
This commit is contained in:
Thirunarayanan Balathandayuthapani 2022-01-20 16:30:18 +05:30
parent a0f711e928
commit 28e166d643
4 changed files with 39 additions and 3 deletions

View file

@ -0,0 +1,12 @@
CREATE TABLE t1(c TEXT, KEY(c(3072)))ENGINE=InnoDB;
CREATE PROCEDURE dorepeat()
LOOP
INSERT INTO t1 VALUES ('abc');
UPDATE t1 SET c='cba';
END LOOP
|
connect con1,localhost,root,,,;
CALL dorepeat();
connection default;
# restart: --innodb_buffer_pool_size=5242880
DROP TABLE t1;

View file

@ -0,0 +1 @@
--innodb_buffer_pool_size=1073741824

View file

@ -0,0 +1,21 @@
--source include/have_innodb.inc
--source include/big_test.inc
CREATE TABLE t1(c TEXT, KEY(c(3072)))ENGINE=InnoDB;
DELIMITER |;
CREATE PROCEDURE dorepeat()
LOOP
INSERT INTO t1 VALUES ('abc');
UPDATE t1 SET c='cba';
END LOOP
|
DELIMITER ;|
connect(con1,localhost,root,,,);
send CALL dorepeat();
connection default;
sleep 10;
let $shutdown_timeout=0;
let $restart_parameters=--innodb_buffer_pool_size=5242880;
--source include/restart_mysqld.inc
DROP TABLE t1;

View file

@ -1288,9 +1288,11 @@ static void buf_flush_LRU_list_batch(ulint max, flush_counters_t *n)
static_assert(FIL_NULL > SRV_SPACE_ID_UPPER_BOUND, "consistency"); static_assert(FIL_NULL > SRV_SPACE_ID_UPPER_BOUND, "consistency");
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.LRU); for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.LRU);
bpage && n->flushed + n->evicted < max && bpage &&
UT_LIST_GET_LEN(buf_pool.LRU) > BUF_LRU_MIN_LEN && ((UT_LIST_GET_LEN(buf_pool.LRU) > BUF_LRU_MIN_LEN &&
UT_LIST_GET_LEN(buf_pool.free) < free_limit; ++scanned) UT_LIST_GET_LEN(buf_pool.free) < free_limit &&
n->flushed + n->evicted < max) ||
recv_recovery_is_on()); ++scanned)
{ {
buf_page_t *prev= UT_LIST_GET_PREV(LRU, bpage); buf_page_t *prev= UT_LIST_GET_PREV(LRU, bpage);
const lsn_t oldest_modification= bpage->oldest_modification(); const lsn_t oldest_modification= bpage->oldest_modification();