MySQL 8.4.2
Source Code Documentation
|
These functions handle keyblock caching for ISAM and MyISAM tables. More...
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <algorithm>
#include <bit>
#include "keycache.h"
#include "my_compiler.h"
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_io.h"
#include "my_macros.h"
#include "my_pointer_arithmetic.h"
#include "my_sys.h"
#include "my_thread_local.h"
#include "mysql/my_loglevel.h"
#include "mysql/psi/mysql_cond.h"
#include "mysql/psi/mysql_mutex.h"
#include "mysql/service_mysql_alloc.h"
#include "mysys/mysys_priv.h"
#include "mysys_err.h"
#include "template_utils.h"
#include "thr_mutex.h"
Classes | |
struct | KEYCACHE_PAGE |
struct | HASH_LINK |
struct | BLOCK_LINK |
Macros | |
#define | STRUCT_PTR(TYPE, MEMBER, a) (TYPE *)((char *)(a)-offsetof(TYPE, MEMBER)) |
#define | COND_FOR_REQUESTED 0 |
#define | COND_FOR_SAVED 1 |
#define | BLOCK_ERROR 1 /* an error occurred when performing file i/o */ |
#define | BLOCK_READ 2 /* file block is in the block buffer */ |
#define | BLOCK_IN_SWITCH 4 /* block is preparing to read new page */ |
#define | BLOCK_REASSIGNED 8 /* blk does not accept requests for old page */ |
#define | BLOCK_IN_FLUSH 16 /* block is selected for flush */ |
#define | BLOCK_CHANGED 32 /* block buffer contains a dirty page */ |
#define | BLOCK_IN_USE 64 /* block is not free */ |
#define | BLOCK_IN_EVICTION 128 /* block is selected for eviction */ |
#define | BLOCK_IN_FLUSHWRITE 256 /* block is in write to file */ |
#define | BLOCK_FOR_UPDATE 512 /* block is selected for buffer modification */ |
#define | PAGE_READ 0 |
#define | PAGE_TO_BE_READ 1 |
#define | PAGE_WAIT_TO_BE_READ 2 |
#define | FLUSH_CACHE 2000 /* sort this many blocks at once */ |
#define | KEYCACHE_HASH(f, pos) |
#define | FILE_HASH(f) ((uint)(f) & (CHANGED_BLOCKS_HASH - 1)) |
#define | BLOCK_NUMBER(b) ((uint)(((char *)(b) - (char *)keycache->block_root) / sizeof(BLOCK_LINK))) |
#define | F_B_PRT(_f_, _v_) DBUG_PRINT("assert_fail", (_f_, _v_)) |
Typedefs | |
typedef mysql_cond_t | KEYCACHE_CONDVAR |
Enumerations | |
enum | BLOCK_TEMPERATURE { BLOCK_COLD , BLOCK_WARM , BLOCK_HOT } |
Functions | |
static void | change_key_cache_param (KEY_CACHE *keycache, ulonglong division_limit, ulonglong age_threshold) |
static int | flush_all_key_blocks (KEY_CACHE *keycache, st_keycache_thread_var *thread_var) |
static void | wait_on_queue (KEYCACHE_WQUEUE *wqueue, mysql_mutex_t *mutex, st_keycache_thread_var *thread) |
static void | release_whole_queue (KEYCACHE_WQUEUE *wqueue) |
static void | free_block (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, BLOCK_LINK *block) |
static int | fail_block (BLOCK_LINK *block) |
static int | fail_hlink (HASH_LINK *hlink) |
static int | cache_empty (KEY_CACHE *keycache) |
static uint | next_power (uint value) |
int | init_key_cache (KEY_CACHE *keycache, ulonglong key_cache_block_size, size_t use_mem, ulonglong division_limit, ulonglong age_threshold) |
int | resize_key_cache (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, ulonglong key_cache_block_size, size_t use_mem, ulonglong division_limit, ulonglong age_threshold) |
static void | inc_counter_for_resize_op (KEY_CACHE *keycache) |
static void | dec_counter_for_resize_op (KEY_CACHE *keycache) |
void | end_key_cache (KEY_CACHE *keycache, bool cleanup) |
static void | link_into_queue (KEYCACHE_WQUEUE *wqueue, st_keycache_thread_var *thread) |
Link a thread into double-linked queue of waiting threads. More... | |
static void | unlink_from_queue (KEYCACHE_WQUEUE *wqueue, st_keycache_thread_var *thread) |
Unlink a thread from double-linked queue of waiting threads. More... | |
static void | unlink_changed (BLOCK_LINK *block) |
static void | link_changed (BLOCK_LINK *block, BLOCK_LINK **phead) |
static void | link_to_file_list (KEY_CACHE *keycache, BLOCK_LINK *block, int file, bool unlink_block) |
static void | link_to_changed_list (KEY_CACHE *keycache, BLOCK_LINK *block) |
static void | link_block (KEY_CACHE *keycache, BLOCK_LINK *block, bool hot, bool at_end) |
static void | unlink_block (KEY_CACHE *keycache, BLOCK_LINK *block) |
static void | reg_requests (KEY_CACHE *keycache, BLOCK_LINK *block, int count) |
static void | unreg_request (KEY_CACHE *keycache, BLOCK_LINK *block, int at_end) |
static void | remove_reader (BLOCK_LINK *block) |
static void | wait_for_readers (KEY_CACHE *keycache, BLOCK_LINK *block, st_keycache_thread_var *thread) |
static void | link_hash (HASH_LINK **start, HASH_LINK *hash_link) |
static void | unlink_hash (KEY_CACHE *keycache, HASH_LINK *hash_link) |
static HASH_LINK * | get_hash_link (KEY_CACHE *keycache, int file, my_off_t filepos, st_keycache_thread_var *thread) |
static BLOCK_LINK * | find_key_block (KEY_CACHE *keycache, st_keycache_thread_var *thread, File file, my_off_t filepos, int init_hits_left, int wrmode, int *page_st) |
static void | read_block (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, BLOCK_LINK *block, uint read_length, uint min_length, bool primary) |
uchar * | key_cache_read (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, File file, my_off_t filepos, int level, uchar *buff, uint length, uint block_length, int return_buffer) |
int | key_cache_insert (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, File file, my_off_t filepos, int level, uchar *buff, uint length) |
int | key_cache_write (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, File file, my_off_t filepos, int level, uchar *buff, uint length, uint block_length, int dont_write) |
static int | flush_cached_blocks (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, File file, BLOCK_LINK **cache, BLOCK_LINK **end, enum flush_type type) |
static int | flush_key_blocks_int (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, File file, enum flush_type type) |
int | flush_key_blocks (KEY_CACHE *keycache, st_keycache_thread_var *thread_var, File file, enum flush_type type) |
int | reset_key_cache_counters (std::string_view name, KEY_CACHE *key_cache) |
Variables | |
KEY_CACHE | dflt_key_cache_var |
KEY_CACHE * | dflt_key_cache = &dflt_key_cache_var |
These functions handle keyblock caching for ISAM and MyISAM tables.
One cache can handle many files. It must contain buffers of the same blocksize. init_key_cache() should be used to init cache handler.
The free list (free_block_list) is a stack like structure. When a block is freed by free_block(), it is pushed onto the stack. When a new block is required it is first tried to pop one from the stack. If the stack is empty, it is tried to get a never-used block from the pool. If this is empty too, then a block is taken from the LRU ring, flushing it to disk, if necessary. This is handled in find_key_block(). With the new free list, the blocks can have three temperatures: hot, warm and cold (which is free). This is remembered in the block header by the enum BLOCK_TEMPERATURE temperature variable. Remembering the temperature is necessary to correctly count the number of warm blocks, which is required to decide when blocks are allowed to become hot. Whenever a block is inserted to another (sub-)chain, we take the old and new temperature into account to decide if we got one more or less warm block. blocks_unused is the sum of never used blocks in the pool and of currently free blocks. blocks_used is the number of blocks fetched from the pool and as such gives the maximum number of in-use blocks at any time.
#define BLOCK_ERROR 1 /* an error occurred when performing file i/o */ |
#define BLOCK_FOR_UPDATE 512 /* block is selected for buffer modification */ |
#define BLOCK_IN_EVICTION 128 /* block is selected for eviction */ |
#define BLOCK_IN_FLUSH 16 /* block is selected for flush */ |
#define BLOCK_IN_FLUSHWRITE 256 /* block is in write to file */ |
#define BLOCK_IN_SWITCH 4 /* block is preparing to read new page */ |
#define BLOCK_IN_USE 64 /* block is not free */ |
#define BLOCK_NUMBER | ( | b | ) | ((uint)(((char *)(b) - (char *)keycache->block_root) / sizeof(BLOCK_LINK))) |
#define BLOCK_READ 2 /* file block is in the block buffer */ |
#define BLOCK_REASSIGNED 8 /* blk does not accept requests for old page */ |
#define COND_FOR_REQUESTED 0 |
#define COND_FOR_SAVED 1 |
#define F_B_PRT | ( | _f_, | |
_v_ | |||
) | DBUG_PRINT("assert_fail", (_f_, _v_)) |
#define FILE_HASH | ( | f | ) | ((uint)(f) & (CHANGED_BLOCKS_HASH - 1)) |
#define FLUSH_CACHE 2000 /* sort this many blocks at once */ |
#define KEYCACHE_HASH | ( | f, | |
pos | |||
) |
#define PAGE_READ 0 |
#define PAGE_TO_BE_READ 1 |
#define PAGE_WAIT_TO_BE_READ 2 |
#define STRUCT_PTR | ( | TYPE, | |
MEMBER, | |||
a | |||
) | (TYPE *)((char *)(a)-offsetof(TYPE, MEMBER)) |
typedef mysql_cond_t KEYCACHE_CONDVAR |
enum BLOCK_TEMPERATURE |
|
static |
|
static |
|
inlinestatic |
void end_key_cache | ( | KEY_CACHE * | keycache, |
bool | cleanup | ||
) |
|
static |
|
static |
|
static |
|
static |
|
static |
int flush_key_blocks | ( | KEY_CACHE * | keycache, |
st_keycache_thread_var * | thread_var, | ||
File | file, | ||
enum flush_type | type | ||
) |
|
static |
|
static |
|
static |
|
inlinestatic |
int init_key_cache | ( | KEY_CACHE * | keycache, |
ulonglong | key_cache_block_size, | ||
size_t | use_mem, | ||
ulonglong | division_limit, | ||
ulonglong | age_threshold | ||
) |
int key_cache_insert | ( | KEY_CACHE * | keycache, |
st_keycache_thread_var * | thread_var, | ||
File | file, | ||
my_off_t | filepos, | ||
int | level, | ||
uchar * | buff, | ||
uint | length | ||
) |
uchar * key_cache_read | ( | KEY_CACHE * | keycache, |
st_keycache_thread_var * | thread_var, | ||
File | file, | ||
my_off_t | filepos, | ||
int | level, | ||
uchar * | buff, | ||
uint | length, | ||
uint | block_length, | ||
int | return_buffer | ||
) |
int key_cache_write | ( | KEY_CACHE * | keycache, |
st_keycache_thread_var * | thread_var, | ||
File | file, | ||
my_off_t | filepos, | ||
int | level, | ||
uchar * | buff, | ||
uint | length, | ||
uint | block_length, | ||
int | dont_write | ||
) |
|
static |
|
inlinestatic |
|
static |
Link a thread into double-linked queue of waiting threads.
wqueue | pointer to the queue structure |
thread | pointer to the keycache variables for the thread to be added to the queue |
Queue is represented by a circular list of the keycache variable structures. Since each thread has its own keycache variables, this is equal to a list of threads. The list is double-linked of the type (**prev,*next), accessed by a pointer to the last element.
|
static |
|
static |
|
inlinestatic |
|
static |
|
static |
|
static |
|
static |
int reset_key_cache_counters | ( | std::string_view | name, |
KEY_CACHE * | key_cache | ||
) |
int resize_key_cache | ( | KEY_CACHE * | keycache, |
st_keycache_thread_var * | thread_var, | ||
ulonglong | key_cache_block_size, | ||
size_t | use_mem, | ||
ulonglong | division_limit, | ||
ulonglong | age_threshold | ||
) |
|
static |
|
inlinestatic |
|
static |
Unlink a thread from double-linked queue of waiting threads.
wqueue | pointer to the queue structure |
thread | pointer to the keycache variables for the thread to be removed to the queue |
|
static |
|
static |
|
static |
KEY_CACHE* dflt_key_cache = &dflt_key_cache_var |
KEY_CACHE dflt_key_cache_var |