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.
parent a0f711e9
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;
--innodb_buffer_pool_size=1073741824
--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;
......@@ -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");
for (buf_page_t *bpage= UT_LIST_GET_LAST(buf_pool.LRU);
bpage && n->flushed + n->evicted < max &&
UT_LIST_GET_LEN(buf_pool.LRU) > BUF_LRU_MIN_LEN &&
UT_LIST_GET_LEN(buf_pool.free) < free_limit; ++scanned)
bpage &&
((UT_LIST_GET_LEN(buf_pool.LRU) > BUF_LRU_MIN_LEN &&
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);
const lsn_t oldest_modification= bpage->oldest_modification();
......
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