• Marko Mäkelä's avatar
    MDEV-26827 Make page flushing even faster · a55b951e
    Marko Mäkelä authored
    For more convenient monitoring of something that could greatly affect
    the volume of page writes, we add the status variable
    Innodb_buffer_pool_pages_split that was previously only available
    via information_schema.innodb_metrics as "innodb_page_splits".
    This was suggested by Axel Schwenke.
    
    buf_flush_page_count: Replaced with buf_pool.stat.n_pages_written.
    We protect buf_pool.stat (except n_page_gets) with buf_pool.mutex
    and remove unnecessary export_vars indirection.
    
    buf_pool.flush_list_bytes: Moved from buf_pool.stat.flush_list_bytes.
    Protected by buf_pool.flush_list_mutex.
    
    buf_pool_t::page_cleaner_status: Replaces buf_pool_t::n_flush_LRU_,
    buf_pool_t::n_flush_list_, and buf_pool_t::page_cleaner_is_idle.
    Protected by buf_pool.flush_list_mutex. We will exclusively broadcast
    buf_pool.done_flush_list by the buf_flush_page_cleaner thread,
    and only wait for it when communicating with buf_flush_page_cleaner.
    There is no need to keep a count of pending writes by the
    buf_pool.flush_list processing. A single flag suffices for that.
    
    Waits for page write completion can be performed by
    simply waiting on block->page.lock, or by invoking
    buf_dblwr.wait_for_page_writes().
    
    buf_LRU_block_free_non_file_page(): Broadcast buf_pool.done_free and
    set buf_pool.try_LRU_scan when freeing a page. This would be
    executed also as part of buf_page_write_complete().
    
    buf_page_write_complete(): Do not broadcast buf_pool.done_flush_list,
    and do not acquire buf_pool.mutex unless buf_pool.LRU eviction is needed.
    Let buf_dblwr count all writes to persistent pages and broadcast a
    condition variable when no outstanding writes remain.
    
    buf_flush_page_cleaner(): Prioritize LRU flushing and eviction right after
    "furious flushing" (lsn_limit). Simplify the conditions and reduce the
    hold time of buf_pool.flush_list_mutex. Refuse to shut down
    or sleep if buf_pool.ran_out(), that is, LRU eviction is needed.
    
    buf_pool_t::page_cleaner_wakeup(): Add the optional parameter for_LRU.
    
    buf_LRU_get_free_block(): Protect buf_lru_free_blocks_error_printed
    with buf_pool.mutex. Invoke buf_pool.page_cleaner_wakeup(true) to
    to ensure that buf_flush_page_cleaner() will process the LRU flush
    request.
    
    buf_do_LRU_batch(), buf_flush_list(), buf_flush_list_space():
    Update buf_pool.stat.n_pages_written when submitting writes
    (while holding buf_pool.mutex), not when completing them.
    
    buf_page_t::flush(), buf_flush_discard_page(): Require that
    the page U-latch be acquired upfront, and remove
    buf_page_t::ready_for_flush().
    
    buf_pool_t::delete_from_flush_list(): Remove the parameter "bool clear".
    
    buf_flush_page(): Count pending page writes via buf_dblwr.
    
    buf_flush_try_neighbors(): Take the block of page_id as a parameter.
    If the tablespace is dropped before our page has been written out,
    release the page U-latch.
    
    buf_pool_invalidate(): Let the caller ensure that there are no
    outstanding writes.
    
    buf_flush_wait_batch_end(false),
    buf_flush_wait_batch_end_acquiring_mutex(false):
    Replaced with buf_dblwr.wait_for_page_writes().
    
    buf_flush_wait_LRU_batch_end(): Replaces buf_flush_wait_batch_end(true).
    
    buf_flush_list(): Remove some broadcast of buf_pool.done_flush_list.
    
    buf_flush_buffer_pool(): Invoke also buf_dblwr.wait_for_page_writes().
    
    buf_pool_t::io_pending(), buf_pool_t::n_flush_list(): Remove.
    Outstanding writes are reflected by buf_dblwr.pending_writes().
    
    buf_dblwr_t::init(): New function, to initialize the mutex and
    the condition variables, but not the backing store.
    
    buf_dblwr_t::is_created(): Replaces buf_dblwr_t::is_initialised().
    
    buf_dblwr_t::pending_writes(), buf_dblwr_t::writes_pending:
    Keeps track of writes of persistent data pages.
    
    buf_flush_LRU(): Allow calls while LRU flushing may be in progress
    in another thread.
    
    Tested by Matthias Leich (correctness) and Axel Schwenke (performance)
    a55b951e
buf0rea.h 5.73 KB