MySQL 8.0.39
Source Code Documentation
buf0lru.cc File Reference

The database buffer replacement algorithm. More...

#include "buf0lru.h"
#include "btr0btr.h"
#include "btr0sea.h"
#include "buf0buddy.h"
#include "buf0buf.h"
#include "buf0dblwr.h"
#include "buf0flu.h"
#include "buf0rea.h"
#include "buf0stats.h"
#include "fil0fil.h"
#include "hash0hash.h"
#include "ibuf0ibuf.h"
#include "log0recv.h"
#include "log0write.h"
#include "my_dbug.h"
#include "os0event.h"
#include "os0file.h"
#include "page0zip.h"
#include "srv0mon.h"
#include "srv0srv.h"
#include "sync0rw.h"
#include "trx0trx.h"
#include "ut0byte.h"
#include "ut0rnd.h"

Functions

static bool buf_LRU_block_remove_hashed (buf_page_t *bpage, bool zip, bool ignore_content)
 Takes a block out of the LRU list and page hash table. More...
 
static void buf_LRU_block_free_hashed_page (buf_block_t *block) noexcept
 Puts a file page whose has no hash index to the free list. More...
 
static void incr_LRU_size_in_bytes (buf_page_t *bpage, buf_pool_t *buf_pool)
 Increases LRU size in bytes with page size inline function. More...
 
bool buf_LRU_evict_from_unzip_LRU (buf_pool_t *buf_pool)
 Determines if the unzip_LRU list should be used for evicting a victim instead of the general LRU list. More...
 
static void buf_LRU_drop_page_hash_batch (space_id_t space_id, const page_size_t &page_size, const page_no_t *arr, ulint count)
 Attempts to drop page hash index on a batch of pages belonging to a particular space id. More...
 
static void buf_LRU_drop_page_hash_for_tablespace (buf_pool_t *buf_pool, space_id_t space_id)
 When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page hash index entries belonging to that table. More...
 
static bool buf_page_try_pin (buf_pool_t *buf_pool, buf_page_t *bpage)
 Try to pin the block in buffer pool. More...
 
static void buf_page_unpin (buf_pool_t *buf_pool, buf_page_t *bpage)
 Unpin the block in buffer pool. More...
 
static bool buf_flush_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 check_page_flush_observer (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 remove_page_flush_list (buf_pool_t *buf_pool, buf_page_t *bpage)
 Attempts to remove a single page from flush list. More...
 
static dberr_t remove_pages_flush_list (buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer)
 Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance. More...
 
static bool flush_page_flush_list (buf_pool_t *buf_pool, buf_page_t *bpage)
 Flushes a single page inside a buffer pool instance. More...
 
static dberr_t flush_pages_flush_list (buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer, const trx_t *trx)
 Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that tablespace. More...
 
static void buf_flush_dirty_pages (buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer, bool flush, const trx_t *trx, bool strict)
 Remove or flush all the dirty pages that belong to a given tablespace inside a specific buffer pool instance. More...
 
static void buf_LRU_remove_all_pages (buf_pool_t *buf_pool, ulint id)
 Remove all pages that belong to a given tablespace inside a specific buffer pool instance when we are DISCARDing the tablespace. More...
 
static void buf_LRU_remove_pages (buf_pool_t *buf_pool, space_id_t id, buf_remove_t buf_remove, const trx_t *trx, bool strict)
 Remove pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that tablespace. More...
 
void buf_LRU_flush_or_remove_pages (space_id_t id, buf_remove_t buf_remove, const trx_t *trx, bool strict)
 Flushes all dirty pages or removes all pages belonging to a given tablespace. More...
 
void buf_LRU_insert_zip_clean (buf_page_t *bpage)
 Insert a compressed block into buf_pool->zip_clean in the LRU order. More...
 
static bool buf_LRU_free_from_unzip_LRU_list (buf_pool_t *buf_pool, bool scan_all)
 Try to free an uncompressed page of a compressed block from the unzip LRU list. More...
 
static bool buf_LRU_free_from_common_LRU_list (buf_pool_t *buf_pool, bool scan_all)
 Try to free a clean page from the common LRU list. More...
 
bool buf_LRU_scan_and_free_block (buf_pool_t *buf_pool, bool scan_all)
 Try to free a replaceable block. More...
 
bool buf_LRU_buf_pool_running_out (void)
 Returns true if less than 25 % of the buffer pool in any instance is available. More...
 
buf_block_tbuf_LRU_get_free_only (buf_pool_t *buf_pool)
 Returns a free block from the buf_pool. More...
 
static void buf_LRU_check_size_of_non_data_objects (const buf_pool_t *buf_pool)
 Checks how much of buf_pool is occupied by non-data objects like AHI, lock heaps etc. More...
 
buf_block_tbuf_LRU_get_free_block (buf_pool_t *buf_pool)
 Returns a free block from the buf_pool. More...
 
static size_t calculate_desired_LRU_old_size (const buf_pool_t *buf_pool)
 Calculates the desired number for the old blocks list. More...
 
static void buf_LRU_old_adjust_len (buf_pool_t *buf_pool)
 Moves the LRU_old pointer so that the length of the old blocks list is inside the allowed limits. More...
 
static void buf_LRU_old_init (buf_pool_t *buf_pool)
 Initializes the old blocks pointer in the LRU list. More...
 
static void buf_unzip_LRU_remove_block_if_needed (buf_page_t *bpage)
 Remove a block from the unzip_LRU list if it belonged to the list. More...
 
void buf_LRU_adjust_hp (buf_pool_t *buf_pool, const buf_page_t *bpage)
 Adjust LRU hazard pointers if needed. More...
 
static void buf_LRU_remove_block (buf_page_t *bpage)
 Removes a block from the LRU list. More...
 
void buf_unzip_LRU_add_block (buf_block_t *block, bool old)
 Adds a block to the LRU list of decompressed zip pages. More...
 
static void buf_LRU_add_block_low (buf_page_t *bpage, bool old)
 Adds a block to the LRU list. More...
 
void buf_LRU_add_block (buf_page_t *bpage, bool old)
 Adds a block to the LRU list. More...
 
void buf_LRU_make_block_young (buf_page_t *bpage)
 Moves a block to the start of the LRU list. More...
 
void buf_LRU_make_block_old (buf_page_t *bpage)
 Moves a block to the end of the LRU list. More...
 
bool buf_LRU_free_page (buf_page_t *bpage, bool zip)
 Try to free a block. More...
 
void buf_LRU_block_free_non_file_page (buf_block_t *block)
 Puts a block back to the free list. More...
 
void buf_LRU_free_one_page (buf_page_t *bpage, bool ignore_content)
 Remove one page from LRU list and put it to free list. More...
 
static uint buf_LRU_old_ratio_update_instance (buf_pool_t *buf_pool, uint old_pct, bool adjust)
 Updates buf_pool->LRU_old_ratio for one buffer pool instance. More...
 
uint buf_LRU_old_ratio_update (uint old_pct, bool adjust)
 Updates buf_pool->LRU_old_ratio. More...
 
void buf_LRU_stat_update (void)
 Update the historical stats that we are collecting for LRU eviction policy at the end of each interval. More...
 
void buf_LRU_validate_instance (buf_pool_t *buf_pool)
 Validates the LRU list for one buffer pool instance. More...
 
void buf_LRU_validate (void)
 Validates the LRU list. More...
 
Space_References buf_LRU_count_space_references ()
 Counts number of pages that are still in the LRU for each space instance encountered. More...
 
static void buf_LRU_print_instance (buf_pool_t *buf_pool)
 Prints the LRU list for one buffer pool instance. More...
 
void buf_LRU_print (void)
 Prints the LRU list. More...
 

Variables

constexpr uint32_t BUF_LRU_OLD_TOLERANCE = 20
 The number of blocks from the LRU_old pointer onward, including the block pointed to, must be buf_pool->LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the whole LRU list length, except that the tolerance defined below is allowed. More...
 
constexpr uint32_t BUF_LRU_NON_OLD_MIN_LEN = 5
 The minimum amount of non-old blocks when the LRU_old list exists (that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks). More...
 
static const ulint BUF_LRU_DROP_SEARCH_SIZE = 1024
 When dropping the search hash index entries before deleting an ibd file, we build a local array of pages belonging to that tablespace in the buffer pool. More...
 
static const ulint BUF_LRU_SEARCH_SCAN_THRESHOLD = 100
 We scan these many blocks when looking for a clean page to evict during LRU eviction. More...
 
static std::atomic_bool buf_lru_switched_on_innodb_mon = false
 If we switch on the InnoDB monitor because there are too few available frames in the buffer pool, we set this to true. More...
 
static const ulint BUF_LRU_STAT_N_INTERVAL = 50
 These statistics are not 'of' LRU but 'for' LRU. More...
 
static const ulint BUF_LRU_IO_TO_UNZIP_FACTOR = 50
 Co-efficient with which we multiply I/O operations to equate them with page_zip_decompress() operations. More...
 
static buf_LRU_stat_t buf_LRU_stat_arr [BUF_LRU_STAT_N_INTERVAL]
 Sampled values buf_LRU_stat_cur. More...
 
static ulint buf_LRU_stat_arr_ind
 Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. More...
 
buf_LRU_stat_t buf_LRU_stat_cur
 Current operation counters. More...
 
buf_LRU_stat_t buf_LRU_stat_sum
 Running sum of past values of buf_LRU_stat_cur. More...
 

Heuristics for detecting index scan

uint buf_LRU_old_threshold
 Move blocks to "new" LRU list only if the first access was at least this many milliseconds ago. More...
 
std::chrono::milliseconds get_buf_LRU_old_threshold ()
 Move blocks to "new" LRU list only if the first access was at least this many milliseconds ago. More...
 

Detailed Description

The database buffer replacement algorithm.

Created 11/5/1995 Heikki Tuuri

Function Documentation

◆ buf_flush_dirty_pages()

static void buf_flush_dirty_pages ( buf_pool_t buf_pool,
space_id_t  id,
Flush_observer observer,
bool  flush,
const trx_t trx,
bool  strict 
)
static

Remove or flush all the dirty pages that belong to a given tablespace inside a specific buffer pool instance.

The pages will remain in the LRU list and will be evicted from the LRU list as they age and move towards the tail of the LRU list.

Parameters
[in,out]buf_poolbuffer pool instance
[in]idspace id
[in]observerflush observer
[in]flushflush to disk if true, otherwise remove the pages without flushing
[in]trxtransaction to check if the operation must be interrupted
[in]stricttrue, if no page from tablespace can be in buffer pool just after flush

◆ buf_flush_try_yield()

static bool buf_flush_try_yield ( buf_pool_t buf_pool,
buf_page_t bpage,
size_t  processed,
bool &  restart 
)
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.

Parameters
[in,out]buf_poolbuffer pool instance
[in,out]bpagepage to remove
[in]processednumber of pages processed
[out]restartif caller needs to restart scan
Returns
true if yielded.

◆ buf_LRU_add_block()

void buf_LRU_add_block ( buf_page_t bpage,
bool  old 
)

Adds a block to the LRU list.

Please make sure that the page_size is already set when invoking the function, so that we can get correct page_size from the buffer page when adding a block into LRU

Parameters
bpagein: control block
oldin: true if should be put to the old blocks in the LRU list, else put to the start; if the LRU list is very short, the block is added to the start, regardless of this parameter

◆ buf_LRU_add_block_low()

static void buf_LRU_add_block_low ( buf_page_t bpage,
bool  old 
)
inlinestatic

Adds a block to the LRU list.

Please make sure that the page_size is already set when invoking the function, so that we can get correct page_size from the buffer page when adding a block into LRU

Parameters
[in]bpagecontrol block
[in]oldtrue if should be put to the old blocks in the LRU list, else put to the start; if the LRU list is very short, the block is added to the start, regardless of this parameter

◆ buf_LRU_adjust_hp()

void buf_LRU_adjust_hp ( buf_pool_t buf_pool,
const buf_page_t bpage 
)

Adjust LRU hazard pointers if needed.

Parameters
[in]buf_poolBuffer pool instance
[in]bpageControl block

◆ buf_LRU_block_free_hashed_page()

static void buf_LRU_block_free_hashed_page ( buf_block_t block)
staticnoexcept

Puts a file page whose has no hash index to the free list.

Parameters
[in,out]blockMust contain a file page and be in a state where it can be freed.

◆ buf_LRU_block_free_non_file_page()

void buf_LRU_block_free_non_file_page ( buf_block_t block)

Puts a block back to the free list.

Parameters
[in]blockblock must not contain a file page

◆ buf_LRU_block_remove_hashed()

static bool buf_LRU_block_remove_hashed ( buf_page_t bpage,
bool  zip,
bool  ignore_content 
)
static

Takes a block out of the LRU list and page hash table.

If the block is compressed-only (BUF_BLOCK_ZIP_PAGE), the object will be freed.

The caller must hold buf_pool->LRU_list_mutex, the buf_page_get_mutex() mutex and the appropriate hash_lock. This function will release the buf_page_get_mutex() and the hash_lock.

If a compressed page is freed other compressed pages may be relocated.

Parameters
[in]bpageblock, must contain a file page and be in a state where it can be freed; there may or may not be a hash index to the page
[in]ziptrue if should remove also the compressed page of an uncompressed page
[in]ignore_contenttrue if should ignore page content, since it could be not initialized
Return values
trueif BUF_BLOCK_FILE_PAGE was removed from page_hash. The caller needs to free the page to the free list
falseif BUF_BLOCK_ZIP_PAGE was removed from page_hash. In this case the block is already returned to the buddy allocator.

◆ buf_LRU_buf_pool_running_out()

bool buf_LRU_buf_pool_running_out ( void  )

Returns true if less than 25 % of the buffer pool in any instance is available.

Returns true if less than 25 % of the buffer pool is available.

This can be used in heuristics to prevent huge transactions eating up the whole buffer pool for their locks.

Returns
true if less than 25 % of buffer pool left

◆ buf_LRU_check_size_of_non_data_objects()

static void buf_LRU_check_size_of_non_data_objects ( const buf_pool_t buf_pool)
static

Checks how much of buf_pool is occupied by non-data objects like AHI, lock heaps etc.

Depending on the size of non-data objects this function will either assert or issue a warning and switch on the status monitor.

Parameters
buf_poolin: buffer pool instance

◆ buf_LRU_count_space_references()

Space_References buf_LRU_count_space_references ( )

Counts number of pages that are still in the LRU for each space instance encountered.

Returns
map of space instances into count of pages in LRU.

◆ buf_LRU_drop_page_hash_batch()

static void buf_LRU_drop_page_hash_batch ( space_id_t  space_id,
const page_size_t page_size,
const page_no_t arr,
ulint  count 
)
static

Attempts to drop page hash index on a batch of pages belonging to a particular space id.

Parameters
[in]space_idspace id
[in]page_sizepage size
[in]arrarray of page_no
[in]countnumber of entries in array

◆ buf_LRU_drop_page_hash_for_tablespace()

static void buf_LRU_drop_page_hash_for_tablespace ( buf_pool_t buf_pool,
space_id_t  space_id 
)
static

When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page hash index entries belonging to that table.

This function tries to do that in batch. Note that this is a 'best effort' attempt and does not guarantee that ALL hash entries will be removed.

Parameters
[in]buf_poolbuffer pool instance
[in]space_idspace id

◆ buf_LRU_evict_from_unzip_LRU()

bool buf_LRU_evict_from_unzip_LRU ( buf_pool_t buf_pool)

Determines if the unzip_LRU list should be used for evicting a victim instead of the general LRU list.

Parameters
[in,out]buf_poolbuffer pool instance
Returns
true if should use unzip_LRU

◆ buf_LRU_flush_or_remove_pages()

void buf_LRU_flush_or_remove_pages ( space_id_t  id,
buf_remove_t  buf_remove,
const trx_t trx,
bool  strict = true 
)

Flushes all dirty pages or removes all pages belonging to a given tablespace.

A PROBLEM: if readahead is being started, what guarantees that it will not try to read in pages after this operation has completed?

Parameters
[in]idtablespace ID
[in]buf_removeremove or flush strategy
[in]trxto check if the operation must be interrupted
[in]stricttrue, if no page from tablespace can be in buffer pool just after flush

◆ buf_LRU_free_from_common_LRU_list()

static bool buf_LRU_free_from_common_LRU_list ( buf_pool_t buf_pool,
bool  scan_all 
)
static

Try to free a clean page from the common LRU list.

Parameters
[in,out]buf_poolbuffer pool instance
[in]scan_allscan whole LRU list if true, otherwise scan only up to BUF_LRU_SEARCH_SCAN_THRESHOLD
Returns
true if freed

◆ buf_LRU_free_from_unzip_LRU_list()

static bool buf_LRU_free_from_unzip_LRU_list ( buf_pool_t buf_pool,
bool  scan_all 
)
static

Try to free an uncompressed page of a compressed block from the unzip LRU list.

The compressed page is preserved, and it need not be clean.

Parameters
[in]buf_poolbuffer pool instance
[in]scan_allscan whole LRU list if true, otherwise scan only srv_LRU_scan_depth / 2 blocks
Returns
true if freed

◆ buf_LRU_free_one_page()

void buf_LRU_free_one_page ( buf_page_t bpage,
bool  ignore_content 
)

Remove one page from LRU list and put it to free list.

The caller must hold the LRU list and block mutexes and have page hash latched in X. The latch and the block mutexes will be released.

Parameters
[in,out]bpageblock, must contain a file page and be in a state where it can be freed; there may or may not be a hash index to the page
[in]ignore_contenttrue if should ignore page content, since it could be not initialized

◆ buf_LRU_free_page()

bool buf_LRU_free_page ( buf_page_t bpage,
bool  zip 
)

Try to free a block.

If bpage is a descriptor of a compressed-only page, the descriptor object will be freed as well. NOTE: this function may temporarily release and relock the buf_page_get_mutex(). Furthermore, the page frame will no longer be accessible via bpage. If this function returns true, it will also release the LRU list mutex. The caller must hold the LRU list and buf_page_get_mutex() mutexes.

Parameters
[in]bpageblock to be freed
[in]ziptrue if should remove also the compressed page of an uncompressed page
Returns
true if freed, false otherwise.

◆ buf_LRU_get_free_block()

buf_block_t * buf_LRU_get_free_block ( buf_pool_t buf_pool)

Returns a free block from the buf_pool.

The block is taken off the free list. If free list is empty, blocks are moved from the end of the LRU list to the free list. This function is called from a user thread when it needs a clean block to read in a page. Note that we only ever get a block from the free list. Even when we flush a page or find a page in LRU scan we put it to free list to be used. iteration 0: get a block from free list, success:done if buf_pool->try_LRU_scan is set scan LRU up to srv_LRU_scan_depth to find a clean block the above will put the block on free list success:retry the free list flush one dirty page from tail of LRU to disk the above will put the block on free list success: retry the free list iteration 1: same as iteration 0 except: scan whole LRU list scan LRU list even if buf_pool->try_LRU_scan is not set iteration > 1: same as iteration 1 but sleep 10ms

Parameters
[in,out]buf_poolbuffer pool instance
Returns
the free control block, in state BUF_BLOCK_READY_FOR_USE

◆ buf_LRU_get_free_only()

buf_block_t * buf_LRU_get_free_only ( buf_pool_t buf_pool)

Returns a free block from the buf_pool.

The block is taken off the free list. If it is empty, returns NULL.

Parameters
[in]buf_poolbuffer pool instance
Returns
a free control block, or NULL if the buf_block->free list is empty

◆ buf_LRU_insert_zip_clean()

void buf_LRU_insert_zip_clean ( buf_page_t bpage)

Insert a compressed block into buf_pool->zip_clean in the LRU order.

Parameters
[in]bpagepointer to the block in question

◆ buf_LRU_make_block_old()

void buf_LRU_make_block_old ( buf_page_t bpage)

Moves a block to the end of the LRU list.

Parameters
[in]bpagecontrol block

◆ buf_LRU_make_block_young()

void buf_LRU_make_block_young ( buf_page_t bpage)

Moves a block to the start of the LRU list.

Parameters
[in]bpagecontrol block

◆ buf_LRU_old_adjust_len()

static void buf_LRU_old_adjust_len ( buf_pool_t buf_pool)
inlinestatic

Moves the LRU_old pointer so that the length of the old blocks list is inside the allowed limits.

Parameters
[in]buf_poolbuffer pool instance

◆ buf_LRU_old_init()

static void buf_LRU_old_init ( buf_pool_t buf_pool)
static

Initializes the old blocks pointer in the LRU list.

This function should be called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length.

Parameters
[in,out]buf_poolbuffer pool instance

◆ buf_LRU_old_ratio_update()

uint buf_LRU_old_ratio_update ( uint  old_pct,
bool  adjust 
)

Updates buf_pool->LRU_old_ratio.

Returns
updated old_pct
Parameters
old_pctin: Reserve this percentage of the buffer pool for "old" blocks.
adjustin: true=adjust the LRU list; false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB

◆ buf_LRU_old_ratio_update_instance()

static uint buf_LRU_old_ratio_update_instance ( buf_pool_t buf_pool,
uint  old_pct,
bool  adjust 
)
static

Updates buf_pool->LRU_old_ratio for one buffer pool instance.

Parameters
[in]buf_poolbuffer pool instance
[in]old_pctReserve this percentage of the buffer pool for "old" blocks
[in]adjusttrue=adjust the LRU list; false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB
Returns
updated old_pct

◆ buf_LRU_print()

void buf_LRU_print ( void  )

Prints the LRU list.

◆ buf_LRU_print_instance()

static void buf_LRU_print_instance ( buf_pool_t buf_pool)
static

Prints the LRU list for one buffer pool instance.

Parameters
[in]buf_poolbuffer pool instance

◆ buf_LRU_remove_all_pages()

static void buf_LRU_remove_all_pages ( buf_pool_t buf_pool,
ulint  id 
)
static

Remove all pages that belong to a given tablespace inside a specific buffer pool instance when we are DISCARDing the tablespace.

Parameters
[in,out]buf_poolbuffer pool instance
[in]idspace id

◆ buf_LRU_remove_block()

static void buf_LRU_remove_block ( buf_page_t bpage)
inlinestatic

Removes a block from the LRU list.

Parameters
[in]bpagecontrol block

◆ buf_LRU_remove_pages()

static void buf_LRU_remove_pages ( buf_pool_t buf_pool,
space_id_t  id,
buf_remove_t  buf_remove,
const trx_t trx,
bool  strict 
)
static

Remove pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that tablespace.

The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU only if buf_remove is BUF_REMOVE_FLUSH_NO_WRITE.

Parameters
buf_poolbuffer pool instance
idin: space id
buf_removein: remove or flush strategy
trxto check if the operation must be interrupted
strictin: true if no page from tablespace can be in buffer pool just after flush

◆ buf_LRU_scan_and_free_block()

bool buf_LRU_scan_and_free_block ( buf_pool_t buf_pool,
bool  scan_all 
)

Try to free a replaceable block.

Parameters
[in,out]buf_poolbuffer pool instance
[in]scan_allscan whole LRU list if true, otherwise scan only BUF_LRU_SEARCH_SCAN_THRESHOLD blocks
Returns
true if found and freed

◆ buf_LRU_stat_update()

void buf_LRU_stat_update ( void  )

Update the historical stats that we are collecting for LRU eviction policy at the end of each interval.

◆ buf_LRU_validate()

void buf_LRU_validate ( void  )

Validates the LRU list.

◆ buf_LRU_validate_instance()

void buf_LRU_validate_instance ( buf_pool_t buf_pool)

Validates the LRU list for one buffer pool instance.

Parameters
[in]buf_poolbuffer pool instance

◆ buf_page_try_pin()

static bool buf_page_try_pin ( buf_pool_t buf_pool,
buf_page_t bpage 
)
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.

Parameters
[in,out]buf_poolbuffer pool instance
[in,out]bpagepage to remove
Returns
true if page could be pinned successfully.

◆ buf_page_unpin()

static void buf_page_unpin ( buf_pool_t buf_pool,
buf_page_t bpage 
)
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.

Parameters
[in,out]buf_poolbuffer pool instance
[in,out]bpagepage to remove

◆ buf_unzip_LRU_add_block()

void buf_unzip_LRU_add_block ( buf_block_t block,
bool  old 
)

Adds a block to the LRU list of decompressed zip pages.

Parameters
[in]blockcontrol block
[in]oldtrue if should be put to the end of the list, else put to the start

◆ buf_unzip_LRU_remove_block_if_needed()

static void buf_unzip_LRU_remove_block_if_needed ( buf_page_t bpage)
static

Remove a block from the unzip_LRU list if it belonged to the list.

Parameters
[in]bpagecontrol block

◆ calculate_desired_LRU_old_size()

static size_t calculate_desired_LRU_old_size ( const buf_pool_t buf_pool)
static

Calculates the desired number for the old blocks list.

Parameters
[in]buf_poolbuffer pool instance

◆ check_page_flush_observer()

static bool check_page_flush_observer ( buf_page_t page,
const Flush_observer observer,
space_id_t  space 
)
inlinestatic

Check if a dirty page should be flushed or removed based on space ID and flush observer.

Parameters
[in]pagedirty page in flush list
[in]observerFlush observer
[in]spaceSpace ID
Returns
true, if page should considered for flush or removal.

◆ flush_page_flush_list()

static bool flush_page_flush_list ( buf_pool_t buf_pool,
buf_page_t bpage 
)
static

Flushes a single page inside a buffer pool instance.

Parameters
[in,out]buf_poolbuffer pool instance
[in,out]bpagepage to flush
Returns
true if page was flushed.

◆ flush_pages_flush_list()

static dberr_t flush_pages_flush_list ( buf_pool_t buf_pool,
space_id_t  id,
Flush_observer observer,
const trx_t trx 
)
static

Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that tablespace.

The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU.

Parameters
[in,out]buf_poolbuffer pool instance
[in]idspace id for which to remove or flush pages
[in]observerflush observer
[in]trxtransaction to check if the operation must be interrupted, can be NULL
Return values
DB_SUCCESSif all freed
DB_FAILif not all freed
DB_INTERRUPTEDif the transaction was interrupted

◆ get_buf_LRU_old_threshold()

std::chrono::milliseconds get_buf_LRU_old_threshold ( )

Move blocks to "new" LRU list only if the first access was at least this many milliseconds ago.

Not protected by any mutex or latch.

◆ incr_LRU_size_in_bytes()

static void incr_LRU_size_in_bytes ( buf_page_t bpage,
buf_pool_t buf_pool 
)
inlinestatic

Increases LRU size in bytes with page size inline function.

Parameters
[in]bpagecontrol block
[in]buf_poolbuffer pool instance

◆ remove_page_flush_list()

static bool remove_page_flush_list ( buf_pool_t buf_pool,
buf_page_t bpage 
)
static

Attempts to remove a single page from flush list.

It is fine to skip flush if the page flush is already in progress.

Parameters
[in,out]buf_poolbuffer pool instance
[in,out]bpagepage to remove
Returns
true if page could be removed successfully.

◆ remove_pages_flush_list()

static dberr_t remove_pages_flush_list ( buf_pool_t buf_pool,
space_id_t  id,
Flush_observer observer 
)
static

Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance.

The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. We don't check for interrupt as we must finish the operation. Usually this function is called as a cleanup work after an interrupt is received.

Parameters
[in,out]buf_poolbuffer pool instance
[in]idspace id for which to remove or flush pages
[in]observerflush observer to identify specific pages
Return values
DB_SUCCESSif all freed
DB_FAILif not all freed and caller should call function again.

Variable Documentation

◆ BUF_LRU_DROP_SEARCH_SIZE

const ulint BUF_LRU_DROP_SEARCH_SIZE = 1024
static

When dropping the search hash index entries before deleting an ibd file, we build a local array of pages belonging to that tablespace in the buffer pool.

Following is the size of that array. We also release buf_pool->LRU_list_mutex after scanning this many pages of the flush_list when dropping a table. This is to ensure that other threads are not blocked for extended period of time when using very large buffer pools.

◆ BUF_LRU_IO_TO_UNZIP_FACTOR

const ulint BUF_LRU_IO_TO_UNZIP_FACTOR = 50
static

Co-efficient with which we multiply I/O operations to equate them with page_zip_decompress() operations.

◆ BUF_LRU_NON_OLD_MIN_LEN

constexpr uint32_t BUF_LRU_NON_OLD_MIN_LEN = 5
constexpr

The minimum amount of non-old blocks when the LRU_old list exists (that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).

See also
buf_LRU_old_adjust_len

◆ buf_LRU_old_threshold

uint buf_LRU_old_threshold

Move blocks to "new" LRU list only if the first access was at least this many milliseconds ago.

Not protected by any mutex or latch.

◆ BUF_LRU_OLD_TOLERANCE

constexpr uint32_t BUF_LRU_OLD_TOLERANCE = 20
constexpr

The number of blocks from the LRU_old pointer onward, including the block pointed to, must be buf_pool->LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the whole LRU list length, except that the tolerance defined below is allowed.

Note that the tolerance must be small enough such that for even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not allowed to point to either end of the LRU list.

◆ BUF_LRU_SEARCH_SCAN_THRESHOLD

const ulint BUF_LRU_SEARCH_SCAN_THRESHOLD = 100
static

We scan these many blocks when looking for a clean page to evict during LRU eviction.

◆ buf_LRU_stat_arr

buf_LRU_stat_t buf_LRU_stat_arr[BUF_LRU_STAT_N_INTERVAL]
static

Sampled values buf_LRU_stat_cur.

Not protected by any mutex. Updated by buf_LRU_stat_update().

◆ buf_LRU_stat_arr_ind

ulint buf_LRU_stat_arr_ind
static

Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion.

◆ buf_LRU_stat_cur

buf_LRU_stat_t buf_LRU_stat_cur

Current operation counters.

Not protected by any mutex. Cleared by buf_LRU_stat_update().

◆ BUF_LRU_STAT_N_INTERVAL

const ulint BUF_LRU_STAT_N_INTERVAL = 50
static

These statistics are not 'of' LRU but 'for' LRU.

We keep count of I/O and page_zip_decompress() operations. Based on the statistics, buf_LRU_evict_from_unzip_LRU() decides if we want to evict from unzip_LRU or the regular LRU. From unzip_LRU, we will only evict the uncompressed frame (meaning we can evict dirty blocks as well). From the regular LRU, we will evict the entire block (i.e.: both the uncompressed and compressed data), which must be clean. Number of intervals for which we keep the history of these stats. Each interval is 1 second, defined by the rate at which srv_error_monitor_thread() calls buf_LRU_stat_update().

◆ buf_LRU_stat_sum

buf_LRU_stat_t buf_LRU_stat_sum

Running sum of past values of buf_LRU_stat_cur.

Updated by buf_LRU_stat_update(). Not Protected by any mutex.

◆ buf_lru_switched_on_innodb_mon

std::atomic_bool buf_lru_switched_on_innodb_mon = false
static

If we switch on the InnoDB monitor because there are too few available frames in the buffer pool, we set this to true.