Bug #121250 Fil_shard::do_io() skips complete_io() on DB_PAGE_IS_STALE after prepare_file_for_io()
Description:
Related to Bug#39244016. That fix is already in 8.0/8.4/9.7/trunk. A second bug remains on 8.0, 8.4, and 9.7:
Fil_shard::prepare_file_for_io() increments fil_node_t::n_pending_ios. After it succeeds, every return from Fil_shard::do_io() must call Fil_shard::complete_io() to decrement that counter (and put the file back on the LRU when it hits 0). The ignore_missing() path already does complete_io() + mutex_release().
However, the write path for a stale page whose page_no is past file->size (tablespace truncated while dirty pages remain in the buffer pool) still does only mutex_release() and return DB_PAGE_IS_STALE. n_pending_ios stays elevated and the file never returns to the LRU - later close/truncate/open-file-limit handling can hang.
Trunk is not affected - WL#15464 rewrote do_io() so a complete_io_and_postprocess_result guard always runs after prepare_file_for_io(), including this stale write.
I will attach:
- io_complete_8.0.patch — production complete_io() plus MTR test (applies to current 8.0; same logic on 8.4/9.7)
- io_complete_trunk.patch — MTR test + DEBUG_SYNC only for trunk for regression testing.
How to repeat:
MTR test innodb.tablespace_truncate_fil_shard (in the attached patches).
It dirties pages in a session temporary table, forces the session temp file closed via innodb_set_open_files_limit(15) and many donor tables, then races SET GLOBAL innodb_buf_flush_list_now=ON with disconnect (ibt::Tablespace_pool::free_ts -> fil_truncate_tablespace). DEBUG_SYNC stops in Fil_shard::open_file after FIL_SHARD is released because the open-files right could not be acquired.
Without complete_io() (8.0/8.4/9.7): the flush thread hits the stale page after prepare_file_for_io() and the test hangs (n_pending_ios leak / file not closable).
Suggested fix:
In Fil_shard::do_io(), on the DB_PAGE_IS_STALE return after prepare_file_for_io() succeeded, call complete_io(file, req_type) before mutex_release(), matching the adjacent ignore_missing() path.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.052 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.