1/* Copyright (C) 2006 MySQL AB
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
15
16/* Page cache variable structures */
17
18#ifndef _ma_pagecache_h
19#define _ma_pagecache_h
20C_MODE_START
21
22#include "ma_loghandler_lsn.h"
23#include <m_string.h>
24#include <hash.h>
25
26/* Type of the page */
27enum pagecache_page_type
28{
29 /*
30 Used only for control page type changing during debugging. This define
31 should only be using when using DBUG.
32 */
33 PAGECACHE_EMPTY_PAGE,
34 /* the page does not contain LSN */
35 PAGECACHE_PLAIN_PAGE,
36 /* the page contain LSN (maria tablespace page) */
37 PAGECACHE_LSN_PAGE,
38 /* Page type used when scanning file and we don't care about the type */
39 PAGECACHE_READ_UNKNOWN_PAGE
40};
41
42/*
43 This enum describe lock status changing. every type of page cache will
44 interpret WRITE/READ lock as it need.
45*/
46enum pagecache_page_lock
47{
48 PAGECACHE_LOCK_LEFT_UNLOCKED, /* free -> free */
49 PAGECACHE_LOCK_LEFT_READLOCKED, /* read -> read */
50 PAGECACHE_LOCK_LEFT_WRITELOCKED, /* write -> write */
51 PAGECACHE_LOCK_READ, /* free -> read */
52 PAGECACHE_LOCK_WRITE, /* free -> write */
53 PAGECACHE_LOCK_READ_UNLOCK, /* read -> free */
54 PAGECACHE_LOCK_WRITE_UNLOCK, /* write -> free */
55 PAGECACHE_LOCK_WRITE_TO_READ /* write -> read */
56};
57/*
58 This enum describe pin status changing
59*/
60enum pagecache_page_pin
61{
62 PAGECACHE_PIN_LEFT_PINNED, /* pinned -> pinned */
63 PAGECACHE_PIN_LEFT_UNPINNED, /* unpinned -> unpinned */
64 PAGECACHE_PIN, /* unpinned -> pinned */
65 PAGECACHE_UNPIN /* pinned -> unpinned */
66};
67/* How to write the page */
68enum pagecache_write_mode
69{
70 /* do not write immediately, i.e. it will be dirty page */
71 PAGECACHE_WRITE_DELAY,
72 /* page already is in the file. (key cache insert analogue) */
73 PAGECACHE_WRITE_DONE
74};
75
76/* page number for maria */
77typedef ulonglong pgcache_page_no_t;
78
79/* args for read/write hooks */
80typedef struct st_pagecache_io_hook_args
81{
82 uchar * page;
83 pgcache_page_no_t pageno;
84 uchar * data;
85
86 uchar *crypt_buf; /* when using encryption */
87} PAGECACHE_IO_HOOK_ARGS;
88
89/* file descriptor for Maria */
90typedef struct st_pagecache_file
91{
92 File file;
93
94 /** Cannot be NULL */
95 my_bool (*pre_read_hook)(PAGECACHE_IO_HOOK_ARGS *args);
96 my_bool (*post_read_hook)(int error, PAGECACHE_IO_HOOK_ARGS *args);
97
98 /** Cannot be NULL */
99 my_bool (*pre_write_hook)(PAGECACHE_IO_HOOK_ARGS *args);
100 void (*post_write_hook)(int error, PAGECACHE_IO_HOOK_ARGS *args);
101
102 /** Cannot be NULL */
103 my_bool (*flush_log_callback)(PAGECACHE_IO_HOOK_ARGS *args);
104
105 uchar *callback_data;
106} PAGECACHE_FILE;
107
108/* declare structures that is used by st_pagecache */
109
110struct st_pagecache_block_link;
111typedef struct st_pagecache_block_link PAGECACHE_BLOCK_LINK;
112struct st_pagecache_page;
113typedef struct st_pagecache_page PAGECACHE_PAGE;
114struct st_pagecache_hash_link;
115typedef struct st_pagecache_hash_link PAGECACHE_HASH_LINK;
116
117#include <wqueue.h>
118
119/* Default size of hash for changed files */
120#define MIN_PAGECACHE_CHANGED_BLOCKS_HASH_SIZE 512
121
122#define PAGECACHE_PRIORITY_LOW 0
123#define PAGECACHE_PRIORITY_DEFAULT 3
124#define PAGECACHE_PRIORITY_HIGH 6
125
126/*
127 The page cache structure
128 It also contains read-only statistics parameters.
129*/
130
131typedef struct st_pagecache
132{
133 size_t mem_size; /* specified size of the cache memory */
134 size_t min_warm_blocks; /* min number of warm blocks; */
135 size_t age_threshold; /* age threshold for hot blocks */
136 ulonglong time; /* total number of block link operations */
137 size_t hash_entries; /* max number of entries in the hash table */
138 size_t changed_blocks_hash_size;/* Number of hash buckets for file blocks */
139 ssize_t hash_links; /* max number of hash links */
140 ssize_t hash_links_used; /* number of hash links taken from free links pool */
141 ssize_t disk_blocks; /* max number of blocks in the cache */
142 size_t blocks_used; /* maximum number of concurrently used blocks */
143 size_t blocks_unused; /* number of currently unused blocks */
144 size_t blocks_changed; /* number of currently dirty blocks */
145 size_t warm_blocks; /* number of blocks in warm sub-chain */
146 size_t cnt_for_resize_op; /* counter to block resize operation */
147 size_t blocks_available; /* number of blocks available in the LRU chain */
148 ssize_t blocks; /* max number of blocks in the cache */
149 uint32 block_size; /* size of the page buffer of a cache block */
150 PAGECACHE_HASH_LINK **hash_root;/* arr. of entries into hash table buckets */
151 PAGECACHE_HASH_LINK *hash_link_root;/* memory for hash table links */
152 PAGECACHE_HASH_LINK *free_hash_list;/* list of free hash links */
153 PAGECACHE_BLOCK_LINK *free_block_list;/* list of free blocks */
154 PAGECACHE_BLOCK_LINK *block_root;/* memory for block links */
155 uchar *block_mem; /* memory for block buffers */
156 PAGECACHE_BLOCK_LINK *used_last;/* ptr to the last block of the LRU chain */
157 PAGECACHE_BLOCK_LINK *used_ins;/* ptr to the insertion block in LRU chain */
158 mysql_mutex_t cache_lock; /* to lock access to the cache structure */
159 WQUEUE resize_queue; /* threads waiting during resize operation */
160 WQUEUE waiting_for_hash_link;/* waiting for a free hash link */
161 WQUEUE waiting_for_block; /* requests waiting for a free block */
162 /* hash for dirty file bl.*/
163 PAGECACHE_BLOCK_LINK **changed_blocks;
164 /* hash for other file bl.*/
165 PAGECACHE_BLOCK_LINK **file_blocks;
166
167 /*
168 The following variables are and variables used to hold parameters for
169 initializing the key cache.
170 */
171
172 ulonglong param_buff_size; /* size the memory allocated for the cache */
173 size_t param_block_size; /* size of the blocks in the key cache */
174 size_t param_division_limit; /* min. percentage of warm blocks */
175 size_t param_age_threshold; /* determines when hot block is downgraded */
176
177 /* Statistics variables. These are reset in reset_pagecache_counters(). */
178 size_t global_blocks_changed; /* number of currently dirty blocks */
179 ulonglong global_cache_w_requests;/* number of write requests (write hits) */
180 ulonglong global_cache_write; /* number of writes from cache to files */
181 ulonglong global_cache_r_requests;/* number of read requests (read hits) */
182 ulonglong global_cache_read; /* number of reads from files to cache */
183
184 uint shift; /* block size = 2 ^ shift */
185 myf readwrite_flags; /* Flags to pread/pwrite() */
186 myf org_readwrite_flags; /* Flags to pread/pwrite() at init */
187 my_bool inited;
188 my_bool resize_in_flush; /* true during flush of resize operation */
189 my_bool can_be_used; /* usage of cache for read/write is allowed */
190 my_bool in_init; /* Set to 1 in MySQL during init/resize */
191 my_bool extra_debug; /* set to 1 if one wants extra logging */
192 HASH files_in_flush; /**< files in flush_pagecache_blocks_int() */
193} PAGECACHE;
194
195/** @brief Return values for PAGECACHE_FLUSH_FILTER */
196enum pagecache_flush_filter_result
197{
198 FLUSH_FILTER_SKIP_TRY_NEXT= 0,/**< skip page and move on to next one */
199 FLUSH_FILTER_OK, /**< flush page and move on to next one */
200 FLUSH_FILTER_SKIP_ALL /**< skip page and all next ones */
201};
202/** @brief a filter function type for flush_pagecache_blocks_with_filter() */
203typedef enum pagecache_flush_filter_result
204(*PAGECACHE_FLUSH_FILTER)(enum pagecache_page_type type,
205 pgcache_page_no_t page,
206 LSN rec_lsn, void *arg);
207
208/* The default key cache */
209extern PAGECACHE dflt_pagecache_var, *dflt_pagecache;
210
211extern size_t init_pagecache(PAGECACHE *pagecache, size_t use_mem,
212 uint division_limit, uint age_threshold,
213 uint block_size, uint changed_blocks_hash_size,
214 myf my_read_flags);
215extern size_t resize_pagecache(PAGECACHE *pagecache,
216 size_t use_mem, uint division_limit,
217 uint age_threshold, uint changed_blocks_hash_size);
218extern void change_pagecache_param(PAGECACHE *pagecache, uint division_limit,
219 uint age_threshold);
220
221extern uchar *pagecache_read(PAGECACHE *pagecache,
222 PAGECACHE_FILE *file,
223 pgcache_page_no_t pageno,
224 uint level,
225 uchar *buff,
226 enum pagecache_page_type type,
227 enum pagecache_page_lock lock,
228 PAGECACHE_BLOCK_LINK **link);
229
230#define pagecache_write(P,F,N,L,B,T,O,I,M,K,R) \
231 pagecache_write_part(P,F,N,L,B,T,O,I,M,K,R,0,(P)->block_size)
232
233#define pagecache_inject(P,F,N,L,B,T,O,I,K,R) \
234 pagecache_write_part(P,F,N,L,B,T,O,I,PAGECACHE_WRITE_DONE, \
235 K,R,0,(P)->block_size)
236
237extern my_bool pagecache_write_part(PAGECACHE *pagecache,
238 PAGECACHE_FILE *file,
239 pgcache_page_no_t pageno,
240 uint level,
241 uchar *buff,
242 enum pagecache_page_type type,
243 enum pagecache_page_lock lock,
244 enum pagecache_page_pin pin,
245 enum pagecache_write_mode write_mode,
246 PAGECACHE_BLOCK_LINK **link,
247 LSN first_REDO_LSN_for_page,
248 uint offset,
249 uint size);
250extern void pagecache_unlock(PAGECACHE *pagecache,
251 PAGECACHE_FILE *file,
252 pgcache_page_no_t pageno,
253 enum pagecache_page_lock lock,
254 enum pagecache_page_pin pin,
255 LSN first_REDO_LSN_for_page,
256 LSN lsn, my_bool was_changed);
257extern void pagecache_unlock_by_link(PAGECACHE *pagecache,
258 PAGECACHE_BLOCK_LINK *block,
259 enum pagecache_page_lock lock,
260 enum pagecache_page_pin pin,
261 LSN first_REDO_LSN_for_page,
262 LSN lsn, my_bool was_changed,
263 my_bool any);
264extern void pagecache_unpin(PAGECACHE *pagecache,
265 PAGECACHE_FILE *file,
266 pgcache_page_no_t pageno,
267 LSN lsn);
268extern void pagecache_unpin_by_link(PAGECACHE *pagecache,
269 PAGECACHE_BLOCK_LINK *link,
270 LSN lsn);
271extern void pagecache_set_write_on_delete_by_link(PAGECACHE_BLOCK_LINK *block);
272
273
274/* Results of flush operation (bit field in fact) */
275
276/* The flush is done. */
277#define PCFLUSH_OK 0
278/* There was errors during the flush process. */
279#define PCFLUSH_ERROR 1
280/* Pinned blocks was met and skipped. */
281#define PCFLUSH_PINNED 2
282/* PCFLUSH_ERROR and PCFLUSH_PINNED. */
283#define PCFLUSH_PINNED_AND_ERROR (PCFLUSH_ERROR|PCFLUSH_PINNED)
284
285// initialize file with empty hooks
286void pagecache_file_set_null_hooks(PAGECACHE_FILE*);
287
288#define flush_pagecache_blocks(A,B,C) \
289 flush_pagecache_blocks_with_filter(A,B,C,NULL,NULL)
290extern int flush_pagecache_blocks_with_filter(PAGECACHE *keycache,
291 PAGECACHE_FILE *file,
292 enum flush_type type,
293 PAGECACHE_FLUSH_FILTER filter,
294 void *filter_arg);
295extern my_bool pagecache_delete(PAGECACHE *pagecache,
296 PAGECACHE_FILE *file,
297 pgcache_page_no_t pageno,
298 enum pagecache_page_lock lock,
299 my_bool flush);
300extern my_bool pagecache_delete_by_link(PAGECACHE *pagecache,
301 PAGECACHE_BLOCK_LINK *link,
302 enum pagecache_page_lock lock,
303 my_bool flush);
304extern my_bool pagecache_delete_pages(PAGECACHE *pagecache,
305 PAGECACHE_FILE *file,
306 pgcache_page_no_t pageno,
307 uint page_count,
308 enum pagecache_page_lock lock,
309 my_bool flush);
310extern void end_pagecache(PAGECACHE *keycache, my_bool cleanup);
311extern my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
312 LEX_STRING *str,
313 LSN *min_lsn);
314extern int reset_pagecache_counters(const char *name, PAGECACHE *pagecache);
315extern uchar *pagecache_block_link_to_buffer(PAGECACHE_BLOCK_LINK *block);
316
317extern uint pagecache_pagelevel(PAGECACHE_BLOCK_LINK *block);
318extern void pagecache_add_level_by_link(PAGECACHE_BLOCK_LINK *block,
319 uint level);
320
321/* Functions to handle multiple key caches */
322extern my_bool multi_pagecache_init(void);
323extern void multi_pagecache_free(void);
324extern PAGECACHE *multi_pagecache_search(uchar *key, uint length,
325 PAGECACHE *def);
326extern my_bool multi_pagecache_set(const uchar *key, uint length,
327 PAGECACHE *pagecache);
328extern void multi_pagecache_change(PAGECACHE *old_data,
329 PAGECACHE *new_data);
330extern int reset_pagecache_counters(const char *name,
331 PAGECACHE *pagecache);
332#ifndef DBUG_OFF
333void pagecache_file_no_dirty_page(PAGECACHE *pagecache, PAGECACHE_FILE *file);
334#else
335#define pagecache_file_no_dirty_page(A,B) {}
336#endif
337
338C_MODE_END
339#endif /* _keycache_h */
340