mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
f134f91f90
storage/maria/ma_checkpoint.c: React only on errors during the flush.
298 lines
13 KiB
C
298 lines
13 KiB
C
/* Copyright (C) 2006 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
/* Page cache variable structures */
|
|
|
|
#ifndef _ma_pagecache_h
|
|
#define _ma_pagecache_h
|
|
C_MODE_START
|
|
|
|
#include "ma_loghandler_lsn.h"
|
|
#include <m_string.h>
|
|
#include <hash.h>
|
|
|
|
/* Type of the page */
|
|
enum pagecache_page_type
|
|
{
|
|
/*
|
|
Used only for control page type changing during debugging. This define
|
|
should only be using when using DBUG.
|
|
*/
|
|
PAGECACHE_EMPTY_PAGE,
|
|
/* the page does not contain LSN */
|
|
PAGECACHE_PLAIN_PAGE,
|
|
/* the page contain LSN (maria tablespace page) */
|
|
PAGECACHE_LSN_PAGE,
|
|
/* Page type used when scanning file and we don't care about the type */
|
|
PAGECACHE_READ_UNKNOWN_PAGE
|
|
};
|
|
|
|
/*
|
|
This enum describe lock status changing. every type of page cache will
|
|
interpret WRITE/READ lock as it need.
|
|
*/
|
|
enum pagecache_page_lock
|
|
{
|
|
PAGECACHE_LOCK_LEFT_UNLOCKED, /* free -> free */
|
|
PAGECACHE_LOCK_LEFT_READLOCKED, /* read -> read */
|
|
PAGECACHE_LOCK_LEFT_WRITELOCKED, /* write -> write */
|
|
PAGECACHE_LOCK_READ, /* free -> read */
|
|
PAGECACHE_LOCK_WRITE, /* free -> write */
|
|
PAGECACHE_LOCK_READ_UNLOCK, /* read -> free */
|
|
PAGECACHE_LOCK_WRITE_UNLOCK, /* write -> free */
|
|
PAGECACHE_LOCK_WRITE_TO_READ /* write -> read */
|
|
};
|
|
/*
|
|
This enum describe pin status changing
|
|
*/
|
|
enum pagecache_page_pin
|
|
{
|
|
PAGECACHE_PIN_LEFT_PINNED, /* pinned -> pinned */
|
|
PAGECACHE_PIN_LEFT_UNPINNED, /* unpinned -> unpinned */
|
|
PAGECACHE_PIN, /* unpinned -> pinned */
|
|
PAGECACHE_UNPIN /* pinned -> unpinned */
|
|
};
|
|
/* How to write the page */
|
|
enum pagecache_write_mode
|
|
{
|
|
/* do not write immediately, i.e. it will be dirty page */
|
|
PAGECACHE_WRITE_DELAY,
|
|
/* page already is in the file. (key cache insert analogue) */
|
|
PAGECACHE_WRITE_DONE
|
|
};
|
|
|
|
/* file descriptor for Maria */
|
|
typedef struct st_pagecache_file
|
|
{
|
|
File file;
|
|
} PAGECACHE_FILE;
|
|
|
|
/* page number for maria */
|
|
typedef uint32 pgcache_page_no_t;
|
|
|
|
/* declare structures that is used by st_pagecache */
|
|
|
|
struct st_pagecache_block_link;
|
|
typedef struct st_pagecache_block_link PAGECACHE_BLOCK_LINK;
|
|
struct st_pagecache_page;
|
|
typedef struct st_pagecache_page PAGECACHE_PAGE;
|
|
struct st_pagecache_hash_link;
|
|
typedef struct st_pagecache_hash_link PAGECACHE_HASH_LINK;
|
|
|
|
#include <wqueue.h>
|
|
|
|
typedef my_bool (*pagecache_disk_read_validator)(uchar *page, uchar *data);
|
|
|
|
#define PAGECACHE_CHANGED_BLOCKS_HASH 128 /* must be power of 2 */
|
|
|
|
/*
|
|
The page cache structure
|
|
It also contains read-only statistics parameters.
|
|
*/
|
|
|
|
typedef struct st_pagecache
|
|
{
|
|
size_t mem_size; /* specified size of the cache memory */
|
|
ulong min_warm_blocks; /* min number of warm blocks; */
|
|
ulong age_threshold; /* age threshold for hot blocks */
|
|
ulonglong time; /* total number of block link operations */
|
|
ulong hash_entries; /* max number of entries in the hash table */
|
|
long hash_links; /* max number of hash links */
|
|
long hash_links_used; /* number of hash links taken from free links pool */
|
|
long disk_blocks; /* max number of blocks in the cache */
|
|
ulong blocks_used; /* maximum number of concurrently used blocks */
|
|
ulong blocks_unused; /* number of currently unused blocks */
|
|
ulong blocks_changed; /* number of currently dirty blocks */
|
|
ulong warm_blocks; /* number of blocks in warm sub-chain */
|
|
ulong cnt_for_resize_op; /* counter to block resize operation */
|
|
ulong blocks_available; /* number of blocks available in the LRU chain */
|
|
long blocks; /* max number of blocks in the cache */
|
|
uint32 block_size; /* size of the page buffer of a cache block */
|
|
PAGECACHE_HASH_LINK **hash_root;/* arr. of entries into hash table buckets */
|
|
PAGECACHE_HASH_LINK *hash_link_root;/* memory for hash table links */
|
|
PAGECACHE_HASH_LINK *free_hash_list;/* list of free hash links */
|
|
PAGECACHE_BLOCK_LINK *free_block_list;/* list of free blocks */
|
|
PAGECACHE_BLOCK_LINK *block_root;/* memory for block links */
|
|
uchar HUGE_PTR *block_mem; /* memory for block buffers */
|
|
PAGECACHE_BLOCK_LINK *used_last;/* ptr to the last block of the LRU chain */
|
|
PAGECACHE_BLOCK_LINK *used_ins;/* ptr to the insertion block in LRU chain */
|
|
pthread_mutex_t cache_lock; /* to lock access to the cache structure */
|
|
WQUEUE resize_queue; /* threads waiting during resize operation */
|
|
WQUEUE waiting_for_hash_link;/* waiting for a free hash link */
|
|
WQUEUE waiting_for_block; /* requests waiting for a free block */
|
|
/* hash for dirty file bl.*/
|
|
PAGECACHE_BLOCK_LINK *changed_blocks[PAGECACHE_CHANGED_BLOCKS_HASH];
|
|
/* hash for other file bl.*/
|
|
PAGECACHE_BLOCK_LINK *file_blocks[PAGECACHE_CHANGED_BLOCKS_HASH];
|
|
|
|
/*
|
|
The following variables are and variables used to hold parameters for
|
|
initializing the key cache.
|
|
*/
|
|
|
|
ulonglong param_buff_size; /* size the memory allocated for the cache */
|
|
ulong param_block_size; /* size of the blocks in the key cache */
|
|
ulong param_division_limit; /* min. percentage of warm blocks */
|
|
ulong param_age_threshold; /* determines when hot block is downgraded */
|
|
|
|
/* Statistics variables. These are reset in reset_pagecache_counters(). */
|
|
ulong global_blocks_changed; /* number of currently dirty blocks */
|
|
ulonglong global_cache_w_requests;/* number of write requests (write hits) */
|
|
ulonglong global_cache_write; /* number of writes from cache to files */
|
|
ulonglong global_cache_r_requests;/* number of read requests (read hits) */
|
|
ulonglong global_cache_read; /* number of reads from files to cache */
|
|
|
|
uint shift; /* block size = 2 ^ shift */
|
|
my_bool inited;
|
|
my_bool resize_in_flush; /* true during flush of resize operation */
|
|
my_bool can_be_used; /* usage of cache for read/write is allowed */
|
|
my_bool in_init; /* Set to 1 in MySQL during init/resize */
|
|
HASH files_in_flush; /**< files in flush_pagecache_blocks_int() */
|
|
} PAGECACHE;
|
|
|
|
/** @brief Return values for PAGECACHE_FLUSH_FILTER */
|
|
enum pagecache_flush_filter_result
|
|
{
|
|
FLUSH_FILTER_SKIP_TRY_NEXT= 0,/**< skip page and move on to next one */
|
|
FLUSH_FILTER_OK, /**< flush page and move on to next one */
|
|
FLUSH_FILTER_SKIP_ALL /**< skip page and all next ones */
|
|
};
|
|
/** @brief a filter function type for flush_pagecache_blocks_with_filter() */
|
|
typedef enum pagecache_flush_filter_result
|
|
(*PAGECACHE_FLUSH_FILTER)(enum pagecache_page_type type, pgcache_page_no_t page,
|
|
LSN rec_lsn, void *arg);
|
|
|
|
/* The default key cache */
|
|
extern PAGECACHE dflt_pagecache_var, *dflt_pagecache;
|
|
|
|
extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
|
|
uint division_limit, uint age_threshold,
|
|
uint block_size);
|
|
extern ulong resize_pagecache(PAGECACHE *pagecache,
|
|
size_t use_mem, uint division_limit,
|
|
uint age_threshold);
|
|
extern void change_pagecache_param(PAGECACHE *pagecache, uint division_limit,
|
|
uint age_threshold);
|
|
|
|
#define pagecache_read(P,F,N,L,B,T,K,I) \
|
|
pagecache_valid_read(P,F,N,L,B,T,K,I,0,0)
|
|
|
|
extern uchar *pagecache_valid_read(PAGECACHE *pagecache,
|
|
PAGECACHE_FILE *file,
|
|
pgcache_page_no_t pageno,
|
|
uint level,
|
|
uchar *buff,
|
|
enum pagecache_page_type type,
|
|
enum pagecache_page_lock lock,
|
|
PAGECACHE_BLOCK_LINK **link,
|
|
pagecache_disk_read_validator validator,
|
|
uchar* validator_data);
|
|
|
|
#define pagecache_write(P,F,N,L,B,T,O,I,M,K,R) \
|
|
pagecache_write_part(P,F,N,L,B,T,O,I,M,K,R,0,(P)->block_size,0,0)
|
|
|
|
#define pagecache_inject(P,F,N,L,B,T,O,I,K,R,V,D) \
|
|
pagecache_write_part(P,F,N,L,B,T,O,I,PAGECACHE_WRITE_DONE, \
|
|
K,R,0,(P)->block_size,V,D)
|
|
|
|
extern my_bool pagecache_write_part(PAGECACHE *pagecache,
|
|
PAGECACHE_FILE *file,
|
|
pgcache_page_no_t pageno,
|
|
uint level,
|
|
uchar *buff,
|
|
enum pagecache_page_type type,
|
|
enum pagecache_page_lock lock,
|
|
enum pagecache_page_pin pin,
|
|
enum pagecache_write_mode write_mode,
|
|
PAGECACHE_BLOCK_LINK **link,
|
|
LSN first_REDO_LSN_for_page,
|
|
uint offset,
|
|
uint size,
|
|
pagecache_disk_read_validator validator,
|
|
uchar* validator_data);
|
|
extern void pagecache_unlock(PAGECACHE *pagecache,
|
|
PAGECACHE_FILE *file,
|
|
pgcache_page_no_t pageno,
|
|
enum pagecache_page_lock lock,
|
|
enum pagecache_page_pin pin,
|
|
LSN first_REDO_LSN_for_page,
|
|
LSN lsn);
|
|
extern void pagecache_unlock_by_link(PAGECACHE *pagecache,
|
|
PAGECACHE_BLOCK_LINK *block,
|
|
enum pagecache_page_lock lock,
|
|
enum pagecache_page_pin pin,
|
|
LSN first_REDO_LSN_for_page,
|
|
LSN lsn);
|
|
extern void pagecache_unpin(PAGECACHE *pagecache,
|
|
PAGECACHE_FILE *file,
|
|
pgcache_page_no_t pageno,
|
|
LSN lsn);
|
|
extern void pagecache_unpin_by_link(PAGECACHE *pagecache,
|
|
PAGECACHE_BLOCK_LINK *link,
|
|
LSN lsn);
|
|
|
|
|
|
/* Results of flush operation (bit field in fact) */
|
|
|
|
/* The flush is done. */
|
|
#define PCFLUSH_OK 0
|
|
/* There was errors during the flush process. */
|
|
#define PCFLUSH_ERROR 1
|
|
/* Pinned blocks was met and skipped. */
|
|
#define PCFLUSH_PINNED 2
|
|
/* PCFLUSH_ERROR and PCFLUSH_PINNED. */
|
|
#define PCFLUSH_PINNED_AND_ERROR (PCFLUSH_ERROR|PCFLUSH_PINNED)
|
|
|
|
|
|
#define flush_pagecache_blocks(A,B,C) \
|
|
flush_pagecache_blocks_with_filter(A,B,C,NULL,NULL)
|
|
extern int flush_pagecache_blocks_with_filter(PAGECACHE *keycache,
|
|
PAGECACHE_FILE *file,
|
|
enum flush_type type,
|
|
PAGECACHE_FLUSH_FILTER filter,
|
|
void *filter_arg);
|
|
extern my_bool pagecache_delete(PAGECACHE *pagecache,
|
|
PAGECACHE_FILE *file,
|
|
pgcache_page_no_t pageno,
|
|
enum pagecache_page_lock lock,
|
|
my_bool flush);
|
|
extern my_bool pagecache_delete_pages(PAGECACHE *pagecache,
|
|
PAGECACHE_FILE *file,
|
|
pgcache_page_no_t pageno,
|
|
uint page_count,
|
|
enum pagecache_page_lock lock,
|
|
my_bool flush);
|
|
extern void end_pagecache(PAGECACHE *keycache, my_bool cleanup);
|
|
extern my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
|
|
LEX_STRING *str,
|
|
LSN *min_lsn);
|
|
extern int reset_pagecache_counters(const char *name, PAGECACHE *pagecache);
|
|
|
|
|
|
/* Functions to handle multiple key caches */
|
|
extern my_bool multi_pagecache_init(void);
|
|
extern void multi_pagecache_free(void);
|
|
extern PAGECACHE *multi_pagecache_search(uchar *key, uint length,
|
|
PAGECACHE *def);
|
|
extern my_bool multi_pagecache_set(const uchar *key, uint length,
|
|
PAGECACHE *pagecache);
|
|
extern void multi_pagecache_change(PAGECACHE *old_data,
|
|
PAGECACHE *new_data);
|
|
extern int reset_pagecache_counters(const char *name,
|
|
PAGECACHE *pagecache);
|
|
|
|
C_MODE_END
|
|
#endif /* _keycache_h */
|