![]() |
MySQL 26.7.0
Source Code Documentation
|
The database buffer buf_pool flush algorithm. More...
#include <math.h>#include <my_dbug.h>#include <mysql/service_thd_wait.h>#include <sys/types.h>#include <time.h>#include "buf0buf.h"#include "buf0checksum.h"#include "buf0flu.h"#include "ha_prototypes.h"#include "my_inttypes.h"#include "sql_thd_internal_api.h"#include "page0zip.h"#include "arch0arch.h"#include "buf0lru.h"#include "buf0rea.h"#include "fil0fil.h"#include "fil0pages_persistence_interface.h"#include "fsp0sysspace.h"#include "ibuf0ibuf.h"#include "log0chkp.h"#include "log0handler_interface.h"#include "log0helpers.h"#include "my_compiler.h"#include "os0file.h"#include "os0thread-create.h"#include "page0page.h"#include "srv0mon.h"#include "srv0srv.h"#include "srv0start.h"#include "trx0purge.h"#include "trx0sys.h"#include "ut0byte.h"#include "ut0math.h"#include "ut0stage.h"Classes | |
| struct | page_cleaner_slot_t |
| Page cleaner request state for each buffer pool instance. More... | |
| struct | page_cleaner_t |
| Page cleaner structure common for all threads. More... | |
| struct | Check |
| Functor to validate the flush list. More... | |
Namespaces | |
| namespace | Adaptive_flush |
Enumerations | |
| enum | page_cleaner_state_t { PAGE_CLEANER_STATE_NONE = 0 , PAGE_CLEANER_STATE_REQUESTED , PAGE_CLEANER_STATE_FLUSHING , PAGE_CLEANER_STATE_FINISHED } |
| State for page cleaner array slot. More... | |
Functions | |
| lsn_t | get_flush_sync_lsn () noexcept |
| Get the lsn up to which data pages are to be synchronously flushed. More... | |
| static void | buf_flush_sync_datafiles () |
| Flush a batch of writes to the datafiles that have already been written to the dblwr buffer on disk. More... | |
| static void | buf_flush_page_coordinator_thread () |
| Thread tasked with flushing dirty pages from the buffer pools. More... | |
| static void | buf_flush_page_cleaner_thread () |
| Worker thread of page_cleaner. More... | |
| static void | incr_flush_list_size_in_bytes (buf_block_t *block, buf_pool_t *buf_pool) |
| Increases flush_list size in bytes with the page size in inline function. More... | |
| static bool | buf_flush_validate_low (const buf_pool_t *buf_pool) |
| Validate a buffer pool instance flush list. More... | |
| static bool | buf_flush_validate_skip (buf_pool_t *buf_pool) |
| Validates the flush list some of the time. More... | |
| bool | buf_are_flush_lists_empty_validate (void) |
| Checks if all flush lists are empty. More... | |
| static bool | buf_flush_list_order_validate (lsn_t earlier_added_lsn, lsn_t new_added_lsn) |
| Checks that order of two consecutive pages in flush list would be valid, according to their oldest_modification values. More... | |
| static lsn_t | buf_flush_borrow_lsn (const buf_pool_t *buf_pool) |
| Borrows LSN from the recent added dirty page to the flush list. More... | |
| void | buf_flush_insert_into_flush_list (buf_pool_t *buf_pool, buf_block_t *block) |
| Inserts a modified block into the flush list. More... | |
| void | buf_flush_note_oldest_modification (buf_pool_t *buf_pool, buf_block_t *block, lsn_t start_lsn) |
As part of buf_flush_note_modification() we are noting the oldest modification for the block. More... | |
| bool | buf_flush_ready_for_replace (const buf_page_t *bpage) |
| Returns true if the file page block is immediately suitable for replacement, i.e., the transition FILE_PAGE => NOT_USED allowed. More... | |
| static bool | buf_flush_ready_for_flush_gen (buf_page_t *bpage, buf_flush_t flush_type, bool atomic) |
| Check if the block was modified and was ready for flushing. More... | |
| static bool | buf_flush_was_ready_for_flush (buf_page_t *bpage, buf_flush_t flush_type) |
| Check if the block was modified and was ready for flushing at some point in time during the call. More... | |
| bool | buf_flush_ready_for_flush (buf_page_t *bpage, buf_flush_t flush_type) |
| Check if the block is modified and ready for flushing. More... | |
| void | buf_flush_remove (buf_page_t *bpage) |
| Remove a block from the flush list of modified blocks. More... | |
| void | buf_flush_relocate_on_flush_list (buf_page_t *bpage, buf_page_t *dpage) |
| Relocates a buffer control block on the flush_list. More... | |
| void | buf_flush_write_complete (buf_page_t *bpage) |
| Updates the flush system data structures when a write is completed. More... | |
| void | buf_flush_update_zip_checksum (buf_frame_t *page, ulint size, lsn_t lsn, bool skip_lsn_check) |
| Calculate the checksum of a page from compressed table and update the page. More... | |
| bool | page_is_uncompressed_type (const byte *page) |
| Check if page type is uncompressed. More... | |
| void | buf_flush_init_for_writing (const buf_block_t *block, byte *page, void *page_zip_, lsn_t newest_lsn, bool skip_checksum, bool skip_lsn_check) |
| Initialize a page for writing to the tablespace. More... | |
| static void | buf_flush_write_block_low (buf_page_t *bpage, buf_flush_t flush_type, bool sync) |
| Does an asynchronous write of a buffer page. More... | |
| bool | buf_flush_page (buf_pool_t *buf_pool, buf_page_t *bpage, buf_flush_t flush_type, bool sync) |
| Writes a flushable page asynchronously from the buffer pool to a file. More... | |
| bool | buf_flush_page_try (buf_pool_t *buf_pool, buf_block_t *block) |
| Writes a flushable page asynchronously from the buffer pool to a file. More... | |
| static bool | buf_flush_check_neighbor (const page_id_t &page_id, buf_flush_t flush_type) |
| Check if the page is in buffer pool and can be flushed. More... | |
| static ulint | buf_flush_try_neighbors (const page_id_t &page_id, buf_flush_t flush_type, ulint n_flushed, ulint n_to_flush) |
| Flushes to disk all flushable pages within the flush area. More... | |
| static bool | buf_flush_page_and_try_neighbors (buf_page_t *bpage, buf_flush_t flush_type, ulint n_to_flush, ulint *count) |
| Check if the block is modified and ready for flushing. More... | |
| static ulint | buf_free_from_unzip_LRU_list_batch (buf_pool_t *buf_pool, ulint max) |
| This utility moves the uncompressed frames of pages to the free list. More... | |
| static ulint | buf_flush_LRU_list_batch (buf_pool_t *buf_pool, ulint max) |
| This utility flushes dirty blocks from the end of the LRU list. More... | |
| static ulint | buf_do_LRU_batch (buf_pool_t *buf_pool, ulint max) |
| Flush and move pages from LRU or unzip_LRU list to the free list. More... | |
| static ulint | buf_do_flush_list_batch (buf_pool_t *buf_pool, ulint min_n, lsn_t lsn_limit) |
| This utility flushes dirty blocks from the end of the flush_list. More... | |
| static ulint | buf_flush_batch (buf_pool_t *buf_pool, buf_flush_t flush_type, ulint min_n, lsn_t lsn_limit) |
| This utility flushes dirty blocks from the end of the LRU list or flush_list. More... | |
| static void | buf_flush_stats (ulint page_count_flush, ulint page_count_LRU) |
| Gather the aggregated stats for both flush list and LRU list flushing. More... | |
| static bool | buf_flush_start (buf_pool_t *buf_pool, buf_flush_t flush_type) |
| Start a buffer flush batch for LRU or flush list. More... | |
| static void | buf_flush_end (buf_pool_t *buf_pool, buf_flush_t flush_type) |
| End a buffer flush batch for LRU or flush list. More... | |
| void | buf_flush_await_no_flushing (buf_pool_t *buf_pool, buf_flush_t flush_type) |
| Waits until there's no flush of the given type from given BP instance. More... | |
| bool | buf_flush_do_batch (buf_pool_t *buf_pool, buf_flush_t type, ulint min_n, lsn_t lsn_limit, ulint *n_processed) |
| Do flushing batch of a given type. More... | |
| bool | buf_flush_lists (ulint min_n, lsn_t lsn_limit, ulint *n_processed) |
| This utility flushes dirty blocks from the end of the flush list of all buffer pool instances. More... | |
| bool | buf_flush_single_page_from_LRU (buf_pool_t *buf_pool) |
| This function picks up a single page from the tail of the LRU list, flushes it (if it is dirty), removes it from page_hash and LRU list and puts it on the free list. More... | |
| static ulint | buf_flush_LRU_list (buf_pool_t *buf_pool) |
| Clears up tail of the LRU list of a given buffer pool instance: Put replaceable pages at the tail of LRU to the free list Flush dirty pages at the tail of LRU to the disk The depth to which we scan each buffer pool is controlled by dynamic config parameter innodb_LRU_scan_depth. More... | |
| bool | Adaptive_flush::initialize (ulint n_pages_last) |
| Initialize flush parameters for current iteration. More... | |
| void | Adaptive_flush::set_average () |
| Set average LSN and page flush speed across multiple iterations. More... | |
| ulint | Adaptive_flush::get_pct_for_dirty () |
| Calculates if flushing is required based on number of dirty pages in the buffer pool. More... | |
| ulint | Adaptive_flush::get_pct_for_lsn (lsn_t age) |
| Calculates if flushing is required based on redo generation rate. More... | |
| ulint | Adaptive_flush::set_flush_target_by_lsn (bool sync_flush, lsn_t sync_flush_limit_lsn) |
| Set page flush target based on LSN change and checkpoint age. More... | |
| ulint | Adaptive_flush::set_flush_target_by_page (ulint n_pages_lsn) |
| Set page flush target based on dirty pages in buffer pool. More... | |
| ulint | Adaptive_flush::page_recommendation (ulint last_pages_in, bool is_sync_flush, lsn_t sync_flush_limit_lsn) |
| This function is called approximately once every second by the page_cleaner thread, unless it is sync flushing mode, in which case it is called every small round. More... | |
| static ulint | pc_sleep_if_needed (std::chrono::steady_clock::time_point next_loop_time, int64_t sig_count) |
| Puts the page_cleaner thread to sleep if it has finished work in less than a second. More... | |
| bool | buf_flush_page_cleaner_is_active () |
| Checks if page cleaners are active. More... | |
| void | buf_flush_page_cleaner_init () |
| Initialize page_cleaner. More... | |
| static void | buf_flush_page_cleaner_close (void) |
| Close page_cleaner. More... | |
| static void | pc_request (ulint min_n, lsn_t lsn_limit) |
| Requests for all slots to flush all buffer pool instances. More... | |
| static ulint | pc_flush_slot (void) |
| Do flush for one slot. More... | |
| static bool | pc_wait_finished (ulint *n_flushed_lru, ulint *n_flushed_list) |
| Wait until all flush requests are finished. More... | |
| static void | buf_flush_page_cleaner_disabled_loop (void) |
| Loop used to disable page cleaner threads. More... | |
| void | buf_flush_page_cleaner_disabled_debug_update (THD *, SYS_VAR *, void *, const void *save) |
| Disables page cleaner threads (coordinator and workers). More... | |
| void | buf_flush_fsync () |
| Executes fsync for all tablespaces, to fsync all pages written to disk. More... | |
| void | buf_flush_sync_all_buf_pools () |
| Synchronously flush dirty blocks from the end of the flush list of all buffer pool instances. More... | |
| bool | buf_flush_validate (buf_pool_t *buf_pool) |
| Validates the flush list. More... | |
| static size_t | buf_flush_get_dirty_pages_count (buf_pool_t *buf_pool, Flush_observer *observer, bool abort_when_interrupted) |
| Counts how many dirty pages that belong to a specified flush observer are in a specified BufferPool instance. More... | |
| static size_t | buf_flush_get_dirty_pages_count (Flush_observer *observer, bool abort_when_interrupted) |
| Counts how many dirty pages that belong to a specified flush observer are in BufferPool. More... | |
| size_t | buf_flush_get_dirty_pages_count_for_space (space_id_t space_id) |
| Counts how many dirty pages that belong to a tablespace with a specified ID are in all BufferPool instances. More... | |
| static bool | buf_flush_check_page_flush_condition (buf_page_t *page, const Flush_observer *observer, space_id_t space) |
| Check if a dirty page should be flushed or removed based on space ID and flush observer. More... | |
| static bool | buf_flush_page_try_pin (buf_pool_t *buf_pool, buf_page_t *bpage) |
| Try to pin the block in buffer pool. More... | |
| static void | buf_flush_page_unpin (buf_pool_t *buf_pool, buf_page_t *bpage) |
| Unpin the block in buffer pool. More... | |
| static bool | buf_flush_scan_try_yield (buf_pool_t *buf_pool, buf_page_t *bpage, size_t processed, bool &restart) |
| If we have hogged the resources for too long then release the LRU list and flush list mutexes and do a thread yield. More... | |
| static bool | buf_flush_page_during_flush_list_scan (buf_pool_t *buf_pool, buf_page_t *bpage) |
| Flushes a single page inside a buffer pool instance. More... | |
| static dberr_t | buf_flush_pages_from_flush_list (buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer, const trx_t *trx) |
| Flushes all dirty pages inside a specified buffer pool instance belonging to a given tablespace or belonging to the specified flush observer. More... | |
| static bool | buf_flush_remove_page_from_flush_list (buf_pool_t *buf_pool, buf_page_t *bpage) |
| Attempts to remove a single page from flush list. More... | |
| static dberr_t | buf_flush_remove_pages_from_flush_list (buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer) |
| Remove all dirty pages inside a specified buffer pool instance belonging to a given tablespace or belonging to the specified flush observer from the flush list, keeping the pages dirty. More... | |
| static void | buf_flush_pages (buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer, const trx_t *trx) |
| Flushes all dirty pages inside a specified buffer pool instance belonging to a given tablespace or belonging to the specified flush observer. More... | |
| void | buf_flush_pages (space_id_t id, Flush_observer *observer, const trx_t *trx) |
| Flushes all dirty pages inside all buffer pool instances belonging to a given tablespace or belonging to the specified flush observer. More... | |
Variables | |
| static uint | buf_flush_lsn_scan_factor = 3 |
| Factor for scan length to determine n_pages for intended oldest LSN progress. More... | |
| static lsn_t | buf_flush_sync_lsn = 0 |
| Target oldest LSN for the requested flush_sync. More... | |
| std::atomic< lsn_t > | requested_sync_flush_lsn {0} |
| lsn that indicates there is need to do sync flush operation, 0 if there is no need to trigger the sync flush by page cleaners. More... | |
| os_event_t | buf_flush_event |
| Event to synchronise with the flushing. More... | |
| os_event_t | buf_flush_tick_event |
| Event to wait for one flushing step. More... | |
| constexpr auto | BUF_FLUSH_LIST_SCAN_LIMIT = 1024 |
| We release latches (including buf_pool->LRU_list_mutex) after scanning this many pages of the flush_list when flushing the space or pages watched by a FlushObserver. More... | |
| static ut::unique_ptr< page_cleaner_t > | page_cleaner |
| bool | innodb_page_cleaner_disabled_debug |
| Value of MySQL global variable used to disable page cleaner. More... | |
| constexpr uint32_t | BUF_LRU_MIN_LEN = 256 |
| If LRU list of a buf_pool is less than this size then LRU eviction should not happen. More... | |
| std::chrono::steady_clock::time_point | Adaptive_flush::cur_iter_time |
| Time stamp of current iteration. More... | |
| lsn_t | Adaptive_flush::cur_iter_lsn = 0 |
| LSN at current iteration. More... | |
| ulint | Adaptive_flush::cur_iter_pages_dirty = 0 |
| Number of dirty pages in flush list in current iteration. More... | |
| ulint | Adaptive_flush::cur_iter_dirty_pct = 0 |
| Dirty page percentage in buffer pool. More... | |
| std::chrono::steady_clock::time_point | Adaptive_flush::prev_iter_time |
| Time stamp of previous iteration. More... | |
| ulint | Adaptive_flush::prev_iter_pages_dirty = 0 |
| Number of dirty pages in flush list at previous iteration. More... | |
| ulint | Adaptive_flush::prev_iter_pages_flushed = 0 |
| Actual number of pages flushed by last iteration. More... | |
| lsn_t | Adaptive_flush::lsn_avg_rate = 0 |
| Average redo generation rate. More... | |
| ulint | Adaptive_flush::page_avg_rate = 0 |
| Average page flush rate. More... | |
| lsn_t | Adaptive_flush::prev_lsn = 0 |
| LSN when last average rates are computed. More... | |
| std::chrono::steady_clock::time_point | Adaptive_flush::prev_time |
| Time stamp when last average rates are computed. More... | |
| ulint | Adaptive_flush::n_iterations = 0 |
| Number of iteration till average rates are computed. More... | |
| ulint | Adaptive_flush::sum_pages = 0 |
| Pages flushed till last average rates are computed. More... | |
The database buffer buf_pool flush algorithm.
Created 11/11/1995 Heikki Tuuri
| enum page_cleaner_state_t |
State for page cleaner array slot.
| bool buf_are_flush_lists_empty_validate | ( | ) |
Checks if all flush lists are empty.
It is supposed to be used in single thread, during startup or shutdown. Hence it does not acquire lock and it is caller's responsibility to guarantee that flush lists are not changed in background.
|
static |
This utility flushes dirty blocks from the end of the flush_list.
The calling thread is not allowed to own any latches on pages!
| [in] | buf_pool | buffer pool instance |
| [in] | min_n | wished minimum number of blocks flushed (it is not guaranteed that the actual number is that big, though) |
| [in] | lsn_limit | all blocks whose oldest_modification is smaller than this should be flushed (if their number does not exceed min_n) |
|
static |
Flush and move pages from LRU or unzip_LRU list to the free list.
Whether LRU or unzip_LRU is used depends on the state of the system.
| [in] | buf_pool | buffer pool instance |
| [in] | max | desired number of blocks in the free_list |
| void buf_flush_await_no_flushing | ( | buf_pool_t * | buf_pool, |
| buf_flush_t | flush_type | ||
| ) |
Waits until there's no flush of the given type from given BP instance.
Note that in case of BUF_FLUSH_LIST and BUF_FLUSH_LRU we also make sure there's no ongoing batch initialization (which could lead to flushes). The BUF_FLUSH_SINGLE_PAGE does not have batch initialization. Note, that we return as soon as there is no flush, but in general a new one could start right after we've returned (it's up to the caller to prevent this). If buf_pool is nullptr, then it will await a moment with no flushes for each BP instance in turn, which in general doesn't imply there was a single moment when all instances were quiescent - it's up to the caller to ensure that.
| [in] | buf_pool | The specific buffer pool instance to check. Can be null, if we want to wait for each buf_pool in turn. |
| [in] | flush_type | Flush type. |
|
static |
This utility flushes dirty blocks from the end of the LRU list or flush_list.
NOTE 1: in the case of an LRU flush the calling thread may own latches to pages: to avoid deadlocks, this function must be written so that it cannot end up waiting for these latches! NOTE 2: in the case of a flush list flush, the calling thread is not allowed to own any latches on pages!
| [in] | buf_pool | buffer pool instance |
| [in] | flush_type | BUF_FLUSH_LRU or BUF_FLUSH_LIST; if BUF_FLUSH_LIST, then the caller must not own any latches on pages |
| [in] | min_n | wished minimum number of blocks flushed (it is not guaranteed that the actual number is that big, though) |
| [in] | lsn_limit | in the case of BUF_FLUSH_LIST all blocks whose oldest_modification is smaller than this should be flushed (if their number does not exceed min_n), otherwise ignored |
|
inlinestatic |
Borrows LSN from the recent added dirty page to the flush list.
This should be the lsn which we may use to mark pages dirtied without underlying redo records, when we add them to the flush list.
The lsn should be chosen in a way which will guarantee that we will not destroy checkpoint calculations if we inserted a new dirty page with such lsn to the flush list. This is strictly related to the limitations we put on the relaxed order in flush lists, which have direct impact on computation of lsn available for next checkpoint.
Therefore when the flush list is empty, the lsn is chosen as the maximum lsn up to which we know, that all dirty pages with smaller oldest_modification were added to the flush list.
This guarantees that the limitations put on the relaxed order are hold and lsn available for next checkpoint is not miscalculated.
| [in] | buf_pool | buffer pool instance |
|
static |
Check if the page is in buffer pool and can be flushed.
| [in] | page_id | page id |
| [in] | flush_type | BUF_FLUSH_LRU or BUF_FLUSH_LIST |
|
inlinestatic |
Check if a dirty page should be flushed or removed based on space ID and flush observer.
| [in] | page | dirty page in flush list |
| [in] | observer | Flush observer |
| [in] | space | Space ID |
| bool buf_flush_do_batch | ( | buf_pool_t * | buf_pool, |
| buf_flush_t | type, | ||
| ulint | min_n, | ||
| lsn_t | lsn_limit, | ||
| ulint * | n_processed | ||
| ) |
Do flushing batch of a given type.
NOTE: The calling thread is not allowed to own any latches on pages!
| [in,out] | buf_pool | buffer pool instance |
| [in] | type | flush type |
| [in] | min_n | wished minimum number of blocks flushed (it is not guaranteed that the actual number is that big, though) |
| [in] | lsn_limit | in the case BUF_FLUSH_LIST all blocks whose oldest_modification is smaller than this should be flushed (if their number does not exceed min_n), otherwise ignored |
| [out] | n_processed | the number of pages which were processed is passed back to caller. Ignored if NULL |
| true | if a batch was queued successfully. |
| false | if another batch of same type was already running. |
|
static |
End a buffer flush batch for LRU or flush list.
| [in] | buf_pool | buffer pool instance |
| [in] | flush_type | BUF_FLUSH_LRU or BUF_FLUSH_LIST |
| void buf_flush_fsync | ( | ) |
Executes fsync for all tablespaces, to fsync all pages written to disk.
|
static |
Counts how many dirty pages that belong to a specified flush observer are in a specified BufferPool instance.
| [in] | buf_pool | BufferPool instance to check dirty pages in. |
| [in] | observer | The observer instance to count dirty pages for. |
| [in] | abort_when_interrupted | When true, the counting will be aborted when the observer's transaction gets interrupted. |
abort_when_interrupted was specified and the observer's transaction was interrupted.
|
static |
Counts how many dirty pages that belong to a specified flush observer are in BufferPool.
| [in] | observer | The observer instance to count dirty pages for. |
| [in] | abort_when_interrupted | When true, the counting will be aborted when the observer's transaction gets interrupted. |
abort_when_interrupted was specified and the observer's transaction was interrupted. the observer's transaction was interrupted. | size_t buf_flush_get_dirty_pages_count_for_space | ( | space_id_t | space_id | ) |
Counts how many dirty pages that belong to a tablespace with a specified ID are in all BufferPool instances.
| [in] | space_id | ID of tablespace for which to count the dirty pages. |
| void buf_flush_init_for_writing | ( | const buf_block_t * | block, |
| byte * | page, | ||
| void * | page_zip_, | ||
| lsn_t | newest_lsn, | ||
| bool | skip_checksum, | ||
| bool | skip_lsn_check | ||
| ) |
Initialize a page for writing to the tablespace.
| [in] | block | buffer block; NULL if bypassing the buffer pool |
| [in,out] | page | page frame |
| [in,out] | page_zip_ | compressed page, or NULL if uncompressed |
| [in] | newest_lsn | newest modification LSN to the page |
| [in] | skip_checksum | whether to disable the page checksum |
| [in] | skip_lsn_check | true to skip check for LSN (in DEBUG) |
| void buf_flush_insert_into_flush_list | ( | buf_pool_t * | buf_pool, |
| buf_block_t * | block | ||
| ) |
Inserts a modified block into the flush list.
| [in] | buf_pool | buffer pool instance |
| [in,out] | block | block which is modified |
|
inlinestatic |
Checks that order of two consecutive pages in flush list would be valid, according to their oldest_modification values.
This is used by assertions only.
| [in] | earlier_added_lsn | oldest_modification of page which was added to flush list earlier |
| [in] | new_added_lsn | oldest_modification of page which is being added to flush list |
| true | if the order is valid |
This utility flushes dirty blocks from the end of the flush list of all buffer pool instances.
NOTE: The calling thread is not allowed to own any latches on pages!
| [in] | min_n | wished minimum number of blocks flushed (it is not guaranteed that the actual number is that big, though) |
| [in] | lsn_limit | in the case BUF_FLUSH_LIST all blocks whose oldest_modification is smaller than this should be flushed (if their number does not exceed min_n), otherwise ignored |
| [out] | n_processed | the number of pages which were processed is passed back to caller. Ignored if NULL. |
|
static |
Clears up tail of the LRU list of a given buffer pool instance: Put replaceable pages at the tail of LRU to the free list Flush dirty pages at the tail of LRU to the disk The depth to which we scan each buffer pool is controlled by dynamic config parameter innodb_LRU_scan_depth.
| buf_pool | buffer pool instance |
|
static |
This utility flushes dirty blocks from the end of the LRU list.
The calling thread is not allowed to own any latches on pages! It attempts to make 'max' blocks available in the free list. Note that it is a best effort attempt and it is not guaranteed that after a call to this function there will be 'max' blocks in the free list.
| [in] | buf_pool | buffer pool instance |
| [in] | max | desired number for blocks in the free_list |
| void buf_flush_note_oldest_modification | ( | buf_pool_t * | buf_pool, |
| buf_block_t * | block, | ||
| lsn_t | start_lsn | ||
| ) |
As part of buf_flush_note_modification() we are noting the oldest modification for the block.
If it already has one, it will not be changed.
| [in] | buf_pool | buffer pool instance |
| [in] | block | block which is modified |
| [in] | start_lsn | start lsn of the mtr that modified this block, it will become the oldest modification if it is non-zero |
| bool buf_flush_page | ( | buf_pool_t * | buf_pool, |
| buf_page_t * | bpage, | ||
| buf_flush_t | flush_type, | ||
| bool | sync | ||
| ) |
Writes a flushable page asynchronously from the buffer pool to a file.
NOTE: 1. in simulated aio we must call os_aio_simulated_wake_handler_threads after we have posted a batch of writes! 2. buf_page_get_mutex(bpage) must be held upon entering this function. The LRU list mutex must be held if flush_type == BUF_FLUSH_SINGLE_PAGE. Both mutexes will be released by this function if it returns true.
| [in] | buf_pool | buffer pool instance |
| [in] | bpage | buffer control block |
| [in] | flush_type | type of flush |
| [in] | sync | true if sync IO request |
|
static |
Check if the block is modified and ready for flushing.
If ready to flush then flush the page and try to flush its neighbors. The caller must hold the buffer pool list mutex corresponding to the type of flush.
| [in] | bpage | buffer control block, must be buf_page_in_file(bpage) |
| [in] | flush_type | BUF_FLUSH_LRU or BUF_FLUSH_LIST |
| [in] | n_to_flush | number of pages to flush |
| [in,out] | count | number of pages flushed |
|
static |
Close page_cleaner.
| void buf_flush_page_cleaner_disabled_debug_update | ( | THD * | thd, |
| SYS_VAR * | var, | ||
| void * | var_ptr, | ||
| const void * | save | ||
| ) |
Disables page cleaner threads (coordinator and workers).
It's used by: SET GLOBAL innodb_page_cleaner_disabled_debug = 1 (0).
| [in] | thd | thread handle |
| [in] | var | pointer to system variable |
| [out] | var_ptr | where the formal string goes |
| [in] | save | immediate result from check function |
|
static |
Loop used to disable page cleaner threads.
| void buf_flush_page_cleaner_init | ( | ) |
Initialize page_cleaner.
| bool buf_flush_page_cleaner_is_active | ( | ) |
Checks if page cleaners are active.
Checks if the page_cleaner is in active state.
|
static |
Worker thread of page_cleaner.
|
static |
Thread tasked with flushing dirty pages from the buffer pools.
As of now we'll have only one coordinator.
|
static |
Flushes a single page inside a buffer pool instance.
| [in,out] | buf_pool | buffer pool instance |
| [in,out] | bpage | page to flush |
| bool buf_flush_page_try | ( | buf_pool_t * | buf_pool, |
| buf_block_t * | block | ||
| ) |
Writes a flushable page asynchronously from the buffer pool to a file.
NOTE: block and LRU list mutexes must be held upon entering this function, and they will be released by this function after flushing. This is loosely based on buf_flush_batch() and buf_flush_page().
| [in,out] | buf_pool | buffer pool instance |
| [in,out] | block | buffer control block |
|
static |
Try to pin the block in buffer pool.
Once pinned, the block cannot be moved within flush list or removed. The dirty page can be flushed when we release the flush list mutex. We return without pinning in that case.
| [in,out] | buf_pool | buffer pool instance |
| [in,out] | bpage | page to remove |
|
static |
Unpin the block in buffer pool.
Ensure that the dirty page cannot be flushed even though we need to release the flush list mutex momentarily.
| [in,out] | buf_pool | buffer pool instance |
| [in,out] | bpage | page to remove |
|
static |
Flushes all dirty pages inside a specified buffer pool instance belonging to a given tablespace or belonging to the specified flush observer.
This will handle all pages that were dirty before this call - in case there are more pages made dirty during the call, they may get not flushed. Exactly one of id and observer can be specified valid. If a transaction is specified, its flush observer must be the same as specified in the observer and it will be used to check if the transaction was interrupted, and in such case:
observer is not nullptr, the dirty pages are removed from the flush list. The pages still remain dirty and a part of LRU and are evicted from the list as they age towards the tail of the LRU.| [in] | buf_pool | BufferPool instance |
| [in] | id | Tablespace ID to flush pages from or SPACE_UNKNOWN iff the observer is not nullptr. |
| [in] | observer | Pointer to a FlushObserver to identify specific pages or nullptr. |
| [in] | trx | Pointer to a transaction to check if the operation was interrupted or nullptr if such checks should not be performed. |
| void buf_flush_pages | ( | space_id_t | id, |
| Flush_observer * | observer, | ||
| const trx_t * | trx | ||
| ) |
Flushes all dirty pages inside all buffer pool instances belonging to a given tablespace or belonging to the specified flush observer.
This will handle all pages that were dirty before this call - in case there are more pages made dirty during the call, they may get not flushed. Exactly one of id and observer can be specified valid. If a transaction is specified, its flush observer must be the same as specified in the observer and it will be used to check if the transaction was interrupted, and in such case:
observer is not nullptr, the dirty pages are removed from the flush list. The pages still remain dirty and a part of LRU and are evicted from the list as they age towards the tail of the LRU.| [in] | id | Tablespace ID to flush pages from or SPACE_UNKNOWN iff the observer is not nullptr. |
| [in] | observer | Pointer to a FlushObserver to identify specific pages or nullptr. |
| [in] | trx | Pointer to a transaction to check if the operation was interrupted or nullptr if such checks should not be performed. |
|
static |
Flushes all dirty pages inside a specified buffer pool instance belonging to a given tablespace or belonging to the specified flush observer.
This will handle all pages that were dirty before this call - in case there are more pages made dirty during the call, they may get not flushed. Exactly one of id and observer can be specified valid. If a transaction is specified, its flush observer must be the same as specified in the observer and it will be used to check if the transaction was interrupted, and in such case all not yet processed dirty pages will be left in the flush list.
| [in] | buf_pool | BufferPool instance |
| [in] | id | Tablespace ID to flush pages from or SPACE_UNKNOWN iff the observer is not nullptr. |
| [in] | observer | Pointer to a FlushObserver to identify specific pages or nullptr. |
| [in] | trx | Pointer to a transaction to check if the operation was interrupted or nullptr if such checks should not be performed. |
| DB_SUCCESS | if all pages were flushed |
| DB_FAIL | if not all pages were flushed |
| DB_INTERRUPTED | if the transaction was interrupted |
| bool buf_flush_ready_for_flush | ( | buf_page_t * | bpage, |
| buf_flush_t | flush_type | ||
| ) |
Check if the block is modified and ready for flushing.
Requires buf_page_get_mutex(bpage).
| [in] | bpage | buffer control block, must be buf_page_in_file() |
| [in] | flush_type | type of flush |
|
static |
Check if the block was modified and was ready for flushing.
This is a common part of the logic of buf_flush_was_ready_for_flush() and buf_flush_ready_for_flush() which differ by the tolerance for stale result.
| [in] | bpage | buffer control block, must be buf_page_in_file() |
| [in] | flush_type | type of flush |
| [in] | atomic | false if the caller can tolerate stale data, true if the caller needs accurate answer, which requires the caller to hold buf_page_get_mutex. |
| bool buf_flush_ready_for_replace | ( | const buf_page_t * | bpage | ) |
Returns true if the file page block is immediately suitable for replacement, i.e., the transition FILE_PAGE => NOT_USED allowed.
The caller must hold the LRU list and block mutexes.
| [in] | bpage | buffer control block, must be buf_page_in_file() and in the LRU list |
| void buf_flush_relocate_on_flush_list | ( | buf_page_t * | bpage, |
| buf_page_t * | dpage | ||
| ) |
Relocates a buffer control block on the flush_list.
Note that it is assumed that the contents of bpage have already been copied to dpage. IMPORTANT: When this function is called bpage and dpage are not exact copies of each other. For example, they both will have different "::state". Also the "::list" pointers in dpage may be stale. We need to use the current list node (bpage) to do the list manipulation because the list pointers could have changed between the time that we copied the contents of bpage to the dpage and the flush list manipulation below.
| bpage | in/out: control block being moved |
| dpage | in/out: destination block |
| void buf_flush_remove | ( | buf_page_t * | bpage | ) |
Remove a block from the flush list of modified blocks.
| [in] | bpage | pointer to the block in question |
|
static |
Attempts to remove a single page from flush list.
It is fine to skip flush if the page flush is already in progress. The page is kept dirty.
| [in,out] | buf_pool | buffer pool instance |
| [in,out] | bpage | page to remove |
|
static |
Remove all dirty pages inside a specified buffer pool instance belonging to a given tablespace or belonging to the specified flush observer from the flush list, keeping the pages dirty.
This will handle all pages that were dirty before this call - in case there are more pages made dirty during the call, they may get not removed. Exactly one of id and observer can be specified valid.
| [in] | buf_pool | BufferPool instance |
| [in] | id | Tablespace ID to flush pages from or SPACE_UNKNOWN iff the observer is not nullptr. |
| [in] | observer | Pointer to a FlushObserver to identify specific pages or nullptr. |
| DB_SUCCESS | if all removed |
| DB_FAIL | if not all removed and caller should call function again. |
|
static |
If we have hogged the resources for too long then release the LRU list and flush list mutexes and do a thread yield.
Set the current page to "sticky" so that it is not relocated during the yield. If I/O is started before sticky BIT could be set, we skip yielding. The caller should restart the scan.
| [in,out] | buf_pool | buffer pool instance |
| [in,out] | bpage | page to remove |
| [in] | processed | number of pages processed |
| [out] | restart | if caller needs to restart scan |
| bool buf_flush_single_page_from_LRU | ( | buf_pool_t * | buf_pool | ) |
This function picks up a single page from the tail of the LRU list, flushes it (if it is dirty), removes it from page_hash and LRU list and puts it on the free list.
It is called from user threads when they are unable to find a replaceable page at the tail of the LRU list i.e.: when the background LRU flushing in the page_cleaner thread is not fast enough to keep pace with the workload.
| [in,out] | buf_pool | buffer pool instance |
|
static |
Start a buffer flush batch for LRU or flush list.
| [in] | buf_pool | buffer pool instance |
| [in] | flush_type | BUF_FLUSH_LRU or BUF_FLUSH_LIST |
Gather the aggregated stats for both flush list and LRU list flushing.
| page_count_flush | number of pages flushed from the end of the flush_list |
| page_count_LRU | number of pages flushed from the end of the LRU list |
| void buf_flush_sync_all_buf_pools | ( | ) |
Synchronously flush dirty blocks from the end of the flush list of all buffer pool instances.
NOTE: The calling thread is not allowed to own any latches on pages!
|
static |
Flush a batch of writes to the datafiles that have already been written to the dblwr buffer on disk.
|
static |
Flushes to disk all flushable pages within the flush area.
| [in] | page_id | page id |
| [in] | flush_type | BUF_FLUSH_LRU or BUF_FLUSH_LIST |
| [in] | n_flushed | number of pages flushed so far in this batch |
| [in] | n_to_flush | maximum number of pages we are allowed to flush |
| void buf_flush_update_zip_checksum | ( | buf_frame_t * | page, |
| ulint | size, | ||
| lsn_t | lsn, | ||
| bool | skip_lsn_check | ||
| ) |
Calculate the checksum of a page from compressed table and update the page.
| [in,out] | page | page to update |
| [in] | size | compressed page size |
| [in] | lsn | LSN to stamp on the page |
| [in] | skip_lsn_check | true to skip check for lsn (in DEBUG) |
| bool buf_flush_validate | ( | buf_pool_t * | buf_pool | ) |
Validates the flush list.
|
static |
Validate a buffer pool instance flush list.
| [in] | buf_pool | Instance to validate |
|
static |
Validates the flush list some of the time.
Try buf_flush_validate_low() every this many times
The buf_flush_validate_low() call skip counter. Use a signed type because of the race condition below.
| buf_pool | in: Buffer pool instance |
|
static |
Check if the block was modified and was ready for flushing at some point in time during the call.
Result might be obsolete.
| [in] | bpage | buffer control block, must be buf_page_in_file() |
| [in] | flush_type | type of flush |
|
static |
Does an asynchronous write of a buffer page.
| [in] | bpage | buffer block to write |
| [in] | flush_type | type of flush |
| [in] | sync | true if sync IO request |
| void buf_flush_write_complete | ( | buf_page_t * | bpage | ) |
Updates the flush system data structures when a write is completed.
| [in] | bpage | pointer to the block in question |
|
static |
This utility moves the uncompressed frames of pages to the free list.
Note that this function does not actually flush any data to disk. It just detaches the uncompressed frames from the compressed pages at the tail of the unzip_LRU and puts those freed frames in the free list. Note that it is a best effort attempt and it is not guaranteed that after a call to this function there will be 'max' blocks in the free list. The caller must hold the LRU list mutex.
| [in] | buf_pool | buffer pool instance |
| [in] | max | desired number of blocks in the free_list |
|
noexcept |
Get the lsn up to which data pages are to be synchronously flushed.
|
inlinestatic |
Increases flush_list size in bytes with the page size in inline function.
| block | in: control block |
| buf_pool | in: buffer pool instance |
| bool page_is_uncompressed_type | ( | const byte * | page | ) |
Check if page type is uncompressed.
| [in] | page | page frame |
|
static |
Do flush for one slot.
Requests for all slots to flush all buffer pool instances.
| min_n | wished minimum number of blocks flushed (it is not guaranteed that the actual number is that big) |
| lsn_limit | in the case BUF_FLUSH_LIST all blocks whose oldest_modification is smaller than this should be flushed (if their number does not exceed min_n), otherwise ignored |
|
static |
Puts the page_cleaner thread to sleep if it has finished work in less than a second.
| 0 | wake up by event set, |
| OS_SYNC_TIME_EXCEEDED | if timeout was exceeded |
| next_loop_time | time when next loop iteration should start |
| sig_count | zero or the value returned by previous call of os_event_reset() |
Wait until all flush requests are finished.
| n_flushed_lru | number of pages flushed from the end of the LRU list. |
| n_flushed_list | number of pages flushed from the end of the flush_list. |
| os_event_t buf_flush_event |
Event to synchronise with the flushing.
|
constexpr |
We release latches (including buf_pool->LRU_list_mutex) after scanning this many pages of the flush_list when flushing the space or pages watched by a FlushObserver.
This is to ensure that other threads are not blocked for extended period of time when using very large buffer pools.
|
static |
Factor for scan length to determine n_pages for intended oldest LSN progress.
|
static |
Target oldest LSN for the requested flush_sync.
| os_event_t buf_flush_tick_event |
Event to wait for one flushing step.
|
constexpr |
If LRU list of a buf_pool is less than this size then LRU eviction should not happen.
This is because when we do LRU flushing we also put the blocks on free list. If LRU list is very small then we can end up in thrashing.
| bool innodb_page_cleaner_disabled_debug |
Value of MySQL global variable used to disable page cleaner.
|
static |
| std::atomic<lsn_t> requested_sync_flush_lsn {0} |
lsn that indicates there is need to do sync flush operation, 0 if there is no need to trigger the sync flush by page cleaners.
lsn that indicates there is need to do sync flush operation
Usually this is determined by the log checkpointer periodically