I tried and failed to reproduce the buffer pool starvation. It turns out that when the buf_flush_lru_manager_thread is not running, buf_LRU_get_free_block() will choose the legacy algorithm:
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
|
&& buf_lru_manager_is_active
|
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
|
|| srv_shutdown_state == SRV_SHUTDOWN_CLEANUP)) {
|
The condition buf_lru_manager_is_active would not hold, because innobase_start_or_create_for_mysql() will not set the variable unless it is starting the buf_flush_lru_manager_thread.
For the record, I used the following test case:
--source include/have_innodb.inc
|
--source include/not_embedded.inc
|
|
SET GLOBAL innodb_file_per_table=on;
|
create table t(a char(255),b char(255),c char(255), d char(255) not null unique,
|
primary key(a,b,c))engine=innodb;
|
|
begin;
|
--disable_query_log
|
let $n=30000;
|
while ($n)
|
{
|
eval insert into t values($n,$n,$n,$n);
|
dec $n;
|
}
|
--enable_query_log
|
commit;
|
-- let $restart_parameters=--innodb-read-only --innodb-buffer-pool-size=20m --innodb-buffer-pool-instances=1
|
-- source include/restart_mysqld.inc
|
|
check table t;
|
By default, innodb_buffer_pool_instances would be 0, which would be replaced with 8 if the innodb_buffer_pool_size is large enough.
It seems that MariaDB has little or no regression test coverage of the innodb_empty_free_list_algorithm=backoff (which is the XtraDB default in 10.0 and 10.1), because the size of a single buffer pool instance would be smaller than 20MiB by default. 1280 pages (20MiB at innodb_page_size=16k) is the limit that is enforced by innodb_empty_free_list_algorithm_allowed().
I believe we have worked out the correct conditions for starting/not starting page cleaners / LRU managers in the latest XtraDB source. Specifically, LRU manager has to be started on innodb_read_only too - it evicts in addition to flushing, and so without it, a --innodb-empty-free-list-algorithm=backoff would starve InnoDB of free pages.