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 |
20 | C_MODE_START |
21 | |
22 | #include "ma_loghandler_lsn.h" |
23 | #include <m_string.h> |
24 | #include <hash.h> |
25 | |
26 | /* Type of the page */ |
27 | enum 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 | */ |
46 | enum 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 | */ |
60 | enum 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 */ |
68 | enum 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 */ |
77 | typedef ulonglong pgcache_page_no_t; |
78 | |
79 | /* args for read/write hooks */ |
80 | typedef 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 */ |
90 | typedef 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 | |
110 | struct st_pagecache_block_link; |
111 | typedef struct st_pagecache_block_link PAGECACHE_BLOCK_LINK; |
112 | struct st_pagecache_page; |
113 | typedef struct st_pagecache_page PAGECACHE_PAGE; |
114 | struct st_pagecache_hash_link; |
115 | typedef 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 | |
131 | typedef 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 ; /* 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 */ |
196 | enum 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() */ |
203 | typedef 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 */ |
209 | extern PAGECACHE dflt_pagecache_var, *dflt_pagecache; |
210 | |
211 | extern 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); |
215 | extern size_t resize_pagecache(PAGECACHE *pagecache, |
216 | size_t use_mem, uint division_limit, |
217 | uint age_threshold, uint changed_blocks_hash_size); |
218 | extern void change_pagecache_param(PAGECACHE *pagecache, uint division_limit, |
219 | uint age_threshold); |
220 | |
221 | extern 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 | |
237 | extern 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); |
250 | extern 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); |
257 | extern 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); |
264 | extern void pagecache_unpin(PAGECACHE *pagecache, |
265 | PAGECACHE_FILE *file, |
266 | pgcache_page_no_t pageno, |
267 | LSN lsn); |
268 | extern void pagecache_unpin_by_link(PAGECACHE *pagecache, |
269 | PAGECACHE_BLOCK_LINK *link, |
270 | LSN lsn); |
271 | extern 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 |
286 | void 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) |
290 | extern 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); |
295 | extern 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); |
300 | extern my_bool pagecache_delete_by_link(PAGECACHE *pagecache, |
301 | PAGECACHE_BLOCK_LINK *link, |
302 | enum pagecache_page_lock lock, |
303 | my_bool flush); |
304 | extern 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); |
310 | extern void end_pagecache(PAGECACHE *keycache, my_bool cleanup); |
311 | extern my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, |
312 | LEX_STRING *str, |
313 | LSN *min_lsn); |
314 | extern int reset_pagecache_counters(const char *name, PAGECACHE *pagecache); |
315 | extern uchar *pagecache_block_link_to_buffer(PAGECACHE_BLOCK_LINK *block); |
316 | |
317 | extern uint pagecache_pagelevel(PAGECACHE_BLOCK_LINK *block); |
318 | extern void pagecache_add_level_by_link(PAGECACHE_BLOCK_LINK *block, |
319 | uint level); |
320 | |
321 | /* Functions to handle multiple key caches */ |
322 | extern my_bool multi_pagecache_init(void); |
323 | extern void multi_pagecache_free(void); |
324 | extern PAGECACHE *multi_pagecache_search(uchar *key, uint length, |
325 | PAGECACHE *def); |
326 | extern my_bool multi_pagecache_set(const uchar *key, uint length, |
327 | PAGECACHE *pagecache); |
328 | extern void multi_pagecache_change(PAGECACHE *old_data, |
329 | PAGECACHE *new_data); |
330 | extern int reset_pagecache_counters(const char *name, |
331 | PAGECACHE *pagecache); |
332 | #ifndef DBUG_OFF |
333 | void pagecache_file_no_dirty_page(PAGECACHE *pagecache, PAGECACHE_FILE *file); |
334 | #else |
335 | #define pagecache_file_no_dirty_page(A,B) {} |
336 | #endif |
337 | |
338 | C_MODE_END |
339 | #endif /* _keycache_h */ |
340 | |