MySQL 8.4.0
Source Code Documentation
mf_keycache.cc File Reference

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_LINKget_hash_link (KEY_CACHE *keycache, int file, my_off_t filepos, st_keycache_thread_var *thread)
 
static BLOCK_LINKfind_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)
 
ucharkey_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_CACHEdflt_key_cache = &dflt_key_cache_var
 

Detailed Description

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.

Macro Definition Documentation

◆ BLOCK_CHANGED

#define BLOCK_CHANGED   32 /* block buffer contains a dirty page */

◆ BLOCK_ERROR

#define BLOCK_ERROR   1 /* an error occurred when performing file i/o */

◆ BLOCK_FOR_UPDATE

#define BLOCK_FOR_UPDATE   512 /* block is selected for buffer modification */

◆ BLOCK_IN_EVICTION

#define BLOCK_IN_EVICTION   128 /* block is selected for eviction */

◆ BLOCK_IN_FLUSH

#define BLOCK_IN_FLUSH   16 /* block is selected for flush */

◆ BLOCK_IN_FLUSHWRITE

#define BLOCK_IN_FLUSHWRITE   256 /* block is in write to file */

◆ BLOCK_IN_SWITCH

#define BLOCK_IN_SWITCH   4 /* block is preparing to read new page */

◆ BLOCK_IN_USE

#define BLOCK_IN_USE   64 /* block is not free */

◆ BLOCK_NUMBER

#define BLOCK_NUMBER (   b)     ((uint)(((char *)(b) - (char *)keycache->block_root) / sizeof(BLOCK_LINK)))

◆ BLOCK_READ

#define BLOCK_READ   2 /* file block is in the block buffer */

◆ BLOCK_REASSIGNED

#define BLOCK_REASSIGNED   8 /* blk does not accept requests for old page */

◆ COND_FOR_REQUESTED

#define COND_FOR_REQUESTED   0

◆ COND_FOR_SAVED

#define COND_FOR_SAVED   1

◆ F_B_PRT

#define F_B_PRT (   _f_,
  _v_ 
)    DBUG_PRINT("assert_fail", (_f_, _v_))

◆ FILE_HASH

#define FILE_HASH (   f)    ((uint)(f) & (CHANGED_BLOCKS_HASH - 1))

◆ FLUSH_CACHE

#define FLUSH_CACHE   2000 /* sort this many blocks at once */

◆ KEYCACHE_HASH

#define KEYCACHE_HASH (   f,
  pos 
)
Value:
(((ulong)((pos) / keycache->key_cache_block_size) + (ulong)(f)) & \
(keycache->hash_entries - 1))

◆ PAGE_READ

#define PAGE_READ   0

◆ PAGE_TO_BE_READ

#define PAGE_TO_BE_READ   1

◆ PAGE_WAIT_TO_BE_READ

#define PAGE_WAIT_TO_BE_READ   2

◆ STRUCT_PTR

#define STRUCT_PTR (   TYPE,
  MEMBER,
 
)    (TYPE *)((char *)(a)-offsetof(TYPE, MEMBER))

Typedef Documentation

◆ KEYCACHE_CONDVAR

Enumeration Type Documentation

◆ BLOCK_TEMPERATURE

Enumerator
BLOCK_COLD 
BLOCK_WARM 
BLOCK_HOT 

Function Documentation

◆ cache_empty()

static int cache_empty ( KEY_CACHE keycache)
static

◆ change_key_cache_param()

static void change_key_cache_param ( KEY_CACHE keycache,
ulonglong  division_limit,
ulonglong  age_threshold 
)
static

◆ dec_counter_for_resize_op()

static void dec_counter_for_resize_op ( KEY_CACHE keycache)
inlinestatic

◆ end_key_cache()

void end_key_cache ( KEY_CACHE keycache,
bool  cleanup 
)

◆ fail_block()

static int fail_block ( BLOCK_LINK block)
static

◆ fail_hlink()

static int fail_hlink ( HASH_LINK hlink)
static

◆ find_key_block()

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

◆ flush_all_key_blocks()

static int flush_all_key_blocks ( KEY_CACHE keycache,
st_keycache_thread_var thread_var 
)
static

◆ flush_cached_blocks()

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

◆ flush_key_blocks()

int flush_key_blocks ( KEY_CACHE keycache,
st_keycache_thread_var thread_var,
File  file,
enum flush_type  type 
)

◆ flush_key_blocks_int()

static int flush_key_blocks_int ( KEY_CACHE keycache,
st_keycache_thread_var thread_var,
File  file,
enum flush_type  type 
)
static

◆ free_block()

static void free_block ( KEY_CACHE keycache,
st_keycache_thread_var thread_var,
BLOCK_LINK block 
)
static

◆ get_hash_link()

static HASH_LINK * get_hash_link ( KEY_CACHE keycache,
int  file,
my_off_t  filepos,
st_keycache_thread_var thread 
)
static

◆ inc_counter_for_resize_op()

static void inc_counter_for_resize_op ( KEY_CACHE keycache)
inlinestatic

◆ init_key_cache()

int init_key_cache ( KEY_CACHE keycache,
ulonglong  key_cache_block_size,
size_t  use_mem,
ulonglong  division_limit,
ulonglong  age_threshold 
)

◆ key_cache_insert()

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 
)

◆ key_cache_read()

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 
)

◆ key_cache_write()

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 
)

◆ link_block()

static void link_block ( KEY_CACHE keycache,
BLOCK_LINK block,
bool  hot,
bool  at_end 
)
static

◆ link_changed()

static void link_changed ( BLOCK_LINK block,
BLOCK_LINK **  phead 
)
inlinestatic

◆ link_hash()

static void link_hash ( HASH_LINK **  start,
HASH_LINK hash_link 
)
inlinestatic

◆ link_into_queue()

static void link_into_queue ( KEYCACHE_WQUEUE wqueue,
st_keycache_thread_var thread 
)
static

Link a thread into double-linked queue of waiting threads.

Parameters
wqueuepointer to the queue structure
threadpointer 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.

◆ link_to_changed_list()

static void link_to_changed_list ( KEY_CACHE keycache,
BLOCK_LINK block 
)
static

◆ link_to_file_list()

static void link_to_file_list ( KEY_CACHE keycache,
BLOCK_LINK block,
int  file,
bool  unlink_block 
)
static

◆ next_power()

static uint next_power ( uint  value)
inlinestatic

◆ read_block()

static void read_block ( KEY_CACHE keycache,
st_keycache_thread_var thread_var,
BLOCK_LINK block,
uint  read_length,
uint  min_length,
bool  primary 
)
static

◆ reg_requests()

static void reg_requests ( KEY_CACHE keycache,
BLOCK_LINK block,
int  count 
)
static

◆ release_whole_queue()

static void release_whole_queue ( KEYCACHE_WQUEUE wqueue)
static

◆ remove_reader()

static void remove_reader ( BLOCK_LINK block)
static

◆ reset_key_cache_counters()

int reset_key_cache_counters ( std::string_view  name,
KEY_CACHE key_cache 
)

◆ resize_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 
)

◆ unlink_block()

static void unlink_block ( KEY_CACHE keycache,
BLOCK_LINK block 
)
static

◆ unlink_changed()

static void unlink_changed ( BLOCK_LINK block)
inlinestatic

◆ unlink_from_queue()

static void unlink_from_queue ( KEYCACHE_WQUEUE wqueue,
st_keycache_thread_var thread 
)
static

Unlink a thread from double-linked queue of waiting threads.

Parameters
wqueuepointer to the queue structure
threadpointer to the keycache variables for the thread to be removed to the queue
Note
See link_into_queue

◆ unlink_hash()

static void unlink_hash ( KEY_CACHE keycache,
HASH_LINK hash_link 
)
static

◆ unreg_request()

static void unreg_request ( KEY_CACHE keycache,
BLOCK_LINK block,
int  at_end 
)
static

◆ wait_for_readers()

static void wait_for_readers ( KEY_CACHE keycache,
BLOCK_LINK block,
st_keycache_thread_var thread 
)
static

◆ wait_on_queue()

static void wait_on_queue ( KEYCACHE_WQUEUE wqueue,
mysql_mutex_t mutex,
st_keycache_thread_var thread 
)
static

Variable Documentation

◆ dflt_key_cache

KEY_CACHE* dflt_key_cache = &dflt_key_cache_var

◆ dflt_key_cache_var

KEY_CACHE dflt_key_cache_var