![]() |
MySQL 26.7.0
Source Code Documentation
|
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 "fil0pages_persistence_interface.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... | |
| 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_t * | buf_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_t * | buf_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_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... | |
The database buffer replacement algorithm.
Created 11/5/1995 Heikki Tuuri
| 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
| bpage | in: control block |
| old | in: 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 |
|
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
| [in] | bpage | control block |
| [in] | old | 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 |
| void buf_LRU_adjust_hp | ( | buf_pool_t * | buf_pool, |
| const buf_page_t * | bpage | ||
| ) |
Adjust LRU hazard pointers if needed.
| [in] | buf_pool | Buffer pool instance |
| [in] | bpage | Control block |
|
staticnoexcept |
Puts a file page whose has no hash index to the free list.
| [in,out] | block | Must contain a file page and be in a state where it can be freed. |
| void buf_LRU_block_free_non_file_page | ( | buf_block_t * | block | ) |
Puts a block back to the free list.
| [in] | block | block must not contain a file page |
|
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.
| [in] | bpage | block, 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] | zip | true if should remove also the compressed page of an uncompressed page |
| [in] | ignore_content | true if should ignore page content, since it could be not initialized |
| true | if BUF_BLOCK_FILE_PAGE was removed from page_hash. The caller needs to free the page to the free list |
| false | if BUF_BLOCK_ZIP_PAGE was removed from page_hash. In this case the block is already returned to the buddy allocator. |
| 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.
|
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.
| buf_pool | in: buffer pool instance |
| Space_References buf_LRU_count_space_references | ( | ) |
Counts number of pages that are still in the LRU for each space instance encountered.
| 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.
| [in,out] | buf_pool | buffer pool instance |
|
static |
Try to free a clean page from the common LRU list.
| [in,out] | buf_pool | buffer pool instance |
| [in] | scan_all | scan whole LRU list if true, otherwise scan only up to BUF_LRU_SEARCH_SCAN_THRESHOLD |
|
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.
| [in] | buf_pool | buffer pool instance |
| [in] | scan_all | scan whole LRU list if true, otherwise scan only srv_LRU_scan_depth / 2 blocks |
| 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.
| [in,out] | bpage | block, 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_content | true if should ignore page content, since it could be not initialized |
| 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.
| [in] | bpage | block to be freed |
| [in] | zip | true if should remove also the compressed page of an uncompressed page |
| 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
| [in,out] | buf_pool | buffer pool instance |
| 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.
| [in] | buf_pool | buffer pool instance |
| void buf_LRU_insert_zip_clean | ( | buf_page_t * | bpage | ) |
Insert a compressed block into buf_pool->zip_clean in the LRU order.
| [in] | bpage | pointer to the block in question |
| void buf_LRU_make_block_old | ( | buf_page_t * | bpage | ) |
Moves a block to the end of the LRU list.
| [in] | bpage | control block |
| void buf_LRU_make_block_young | ( | buf_page_t * | bpage | ) |
Moves a block to the start of the LRU list.
| [in] | bpage | control block |
|
inlinestatic |
Moves the LRU_old pointer so that the length of the old blocks list is inside the allowed limits.
| [in] | buf_pool | buffer pool instance |
|
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.
| [in,out] | buf_pool | buffer pool instance |
| uint buf_LRU_old_ratio_update | ( | uint | old_pct, |
| bool | adjust | ||
| ) |
Updates buf_pool->LRU_old_ratio.
| old_pct | in: Reserve this percentage of the buffer pool for "old" blocks. |
| adjust | in: true=adjust the LRU list; false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB |
|
static |
Updates buf_pool->LRU_old_ratio for one buffer pool instance.
| [in] | buf_pool | buffer pool instance |
| [in] | old_pct | Reserve this percentage of the buffer pool for "old" blocks |
| [in] | adjust | true=adjust the LRU list; false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB |
| void buf_LRU_print | ( | void | ) |
Prints the LRU list.
|
static |
Prints the LRU list for one buffer pool instance.
| [in] | buf_pool | buffer pool instance |
|
inlinestatic |
Removes a block from the LRU list.
| [in] | bpage | control block |
| bool buf_LRU_scan_and_free_block | ( | buf_pool_t * | buf_pool, |
| bool | scan_all | ||
| ) |
Try to free a replaceable block.
| [in,out] | buf_pool | buffer pool instance |
| [in] | scan_all | scan whole LRU list if true, otherwise scan only BUF_LRU_SEARCH_SCAN_THRESHOLD blocks |
| void buf_LRU_stat_update | ( | void | ) |
Update the historical stats that we are collecting for LRU eviction policy at the end of each interval.
| void buf_LRU_validate | ( | void | ) |
Validates the LRU list.
| void buf_LRU_validate_instance | ( | buf_pool_t * | buf_pool | ) |
Validates the LRU list for one buffer pool instance.
| [in] | buf_pool | buffer pool instance |
| void buf_unzip_LRU_add_block | ( | buf_block_t * | block, |
| bool | old | ||
| ) |
Adds a block to the LRU list of decompressed zip pages.
| [in] | block | control block |
| [in] | old | true if should be put to the end of the list, else put to the start |
|
static |
Remove a block from the unzip_LRU list if it belonged to the list.
| [in] | bpage | control block |
|
static |
Calculates the desired number for the old blocks list.
| [in] | buf_pool | buffer pool instance |
| 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.
|
inlinestatic |
Increases LRU size in bytes with page size inline function.
| [in] | bpage | control block |
| [in] | buf_pool | buffer pool instance |
|
static |
Co-efficient with which we multiply I/O operations to equate them with page_zip_decompress() operations.
|
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).
| 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.
|
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.
|
static |
We scan these many blocks when looking for a clean page to evict during LRU eviction.
|
static |
Sampled values buf_LRU_stat_cur.
Not protected by any mutex. Updated by buf_LRU_stat_update().
|
static |
Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion.
| buf_LRU_stat_t buf_LRU_stat_cur |
Current operation counters.
Not protected by any mutex. Cleared by buf_LRU_stat_update().
|
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_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.
|
static |
If we switch on the InnoDB monitor because there are too few available frames in the buffer pool, we set this to true.