1
/* Copyright (C) 2001-2006 MySQL AB
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22
Can't create new free memory block if unused memory in block less
23
then QUERY_CACHE_MIN_ALLOCATION_UNIT.
24
if QUERY_CACHE_MIN_ALLOCATION_UNIT == 0 then
25
QUERY_CACHE_MIN_ALLOCATION_UNIT choosed automaticaly
27
#define QUERY_CACHE_MIN_ALLOCATION_UNIT 512
29
/* inittial size of hashes */
30
#define QUERY_CACHE_DEF_QUERY_HASH_SIZE 1024
31
#define QUERY_CACHE_DEF_TABLE_HASH_SIZE 1024
33
/* minimal result data size when data allocated */
34
#define QUERY_CACHE_MIN_RESULT_DATA_SIZE 1024*4
37
start estimation of first result block size only when number of queries
40
#define QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER 3
44
/* memory bins size spacing (see at Query_cache::init_cache (sql_cache.cc)) */
45
#define QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 4
46
#define QUERY_CACHE_MEM_BIN_STEP_PWR2 2
47
#define QUERY_CACHE_MEM_BIN_PARTS_INC 1
48
#define QUERY_CACHE_MEM_BIN_PARTS_MUL 1.2
49
#define QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2 3
51
/* how many free blocks check when finding most suitable before other 'end'
52
of list of free blocks */
53
#define QUERY_CACHE_MEM_BIN_TRY 5
55
/* packing parameters */
56
#define QUERY_CACHE_PACK_ITERATION 2
57
#define QUERY_CACHE_PACK_LIMIT (512*1024L)
59
#define TABLE_COUNTER_TYPE uint
61
struct Query_cache_block;
62
struct Query_cache_block_table;
63
struct Query_cache_table;
64
struct Query_cache_query;
65
struct Query_cache_result;
69
This class represents a node in the linked chain of queries
70
belonging to one table.
72
@note The root of this linked list is not a query-type block, but the table-
73
type block which all queries has in common.
75
struct Query_cache_block_table
77
Query_cache_block_table() {} /* Remove gcc warning */
80
This node holds a position in a static table list belonging
81
to the associated query (base 0).
86
Pointers to the next and previous node, linking all queries with
89
Query_cache_block_table *next, *prev;
92
A pointer to the table-type block which all
93
linked queries has in common.
95
Query_cache_table *parent;
98
A method to calculate the address of the query cache block
99
owning this node. The purpose of this calculation is to
100
make it easier to move the query cache block without having
101
to modify all the pointer addresses.
103
inline Query_cache_block *block();
106
struct Query_cache_block
108
Query_cache_block() {} /* Remove gcc warning */
109
enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG,
110
RES_INCOMPLETE, TABLE, INCOMPLETE};
112
ulong length; // length of all block
113
ulong used; // length of data
115
Not used **pprev, **prev because really needed access to pervious block:
116
*pprev to join free blocks
117
*prev to access to opposite side of list in cyclic sorted list
119
Query_cache_block *pnext,*pprev, // physical next/previous block
120
*next,*prev; // logical next/previous block
122
TABLE_COUNTER_TYPE n_tables; // number of tables in query
124
inline my_bool is_free(void) { return type == FREE; }
125
void init(ulong length);
127
inline uint headers_len();
128
inline uchar* data(void);
129
inline Query_cache_query *query();
130
inline Query_cache_table *table();
131
inline Query_cache_result *result();
132
inline Query_cache_block_table *table(TABLE_COUNTER_TYPE n);
135
struct Query_cache_query
137
ulonglong limit_found_rows;
139
Query_cache_block *res;
143
unsigned int last_pkt_nr;
145
Query_cache_query() {} /* Remove gcc warning */
146
inline void init_n_lock();
147
void unlock_n_destroy();
148
inline ulonglong found_rows() { return limit_found_rows; }
149
inline void found_rows(ulonglong rows) { limit_found_rows= rows; }
150
inline Query_cache_block *result() { return res; }
151
inline void result(Query_cache_block *p) { res= p; }
152
inline NET *writer() { return wri; }
153
inline void writer(NET *p) { wri= p; }
154
inline uint8 tables_type() { return tbls_type; }
155
inline void tables_type(uint8 type) { tbls_type= type; }
156
inline ulong length() { return len; }
157
inline ulong add(ulong packet_len) { return(len+= packet_len); }
158
inline void length(ulong length_arg) { len= length_arg; }
159
inline uchar* query()
161
return (((uchar*)this) + ALIGN_SIZE(sizeof(Query_cache_query)));
165
my_bool try_lock_writing();
166
void unlock_writing();
167
void unlock_reading();
171
struct Query_cache_table
173
Query_cache_table() {} /* Remove gcc warning */
177
/* unique for every engine reference */
178
qc_engine_callback callback_func;
179
/* data need by some engines */
180
ulonglong engine_data_buff;
183
The number of queries depending of this table.
185
int32 m_cached_query_count;
187
inline char *db() { return (char *) data(); }
188
inline char *table() { return tbl; }
189
inline void table(char *table_arg) { tbl= table_arg; }
190
inline uint32 key_length() { return key_len; }
191
inline void key_length(uint32 len) { key_len= len; }
192
inline uint8 type() { return table_type; }
193
inline void type(uint8 t) { table_type= t; }
194
inline qc_engine_callback callback() { return callback_func; }
195
inline void callback(qc_engine_callback fn){ callback_func= fn; }
196
inline ulonglong engine_data() { return engine_data_buff; }
197
inline void engine_data(ulonglong data_arg){ engine_data_buff= data_arg; }
200
return (uchar*)(((uchar*)this)+
201
ALIGN_SIZE(sizeof(Query_cache_table)));
205
struct Query_cache_result
207
Query_cache_result() {} /* Remove gcc warning */
208
Query_cache_block *query;
212
return (uchar*)(((uchar*) this)+
213
ALIGN_SIZE(sizeof(Query_cache_result)));
215
/* data_continue (if not whole packet contained by this block) */
216
inline Query_cache_block *parent() { return query; }
217
inline void parent (Query_cache_block *p) { query=p; }
223
uchar *query_cache_query_get_key(const uchar *record, size_t *length,
225
uchar *query_cache_table_get_key(const uchar *record, size_t *length,
228
extern "C" void query_cache_invalidate_by_MyISAM_filename(const char* filename);
231
struct Query_cache_memory_bin
233
Query_cache_memory_bin() {} /* Remove gcc warning */
238
Query_cache_block *free_blocks;
240
inline void init(ulong size_arg)
250
struct Query_cache_memory_bin_step
252
Query_cache_memory_bin_step() {} /* Remove gcc warning */
256
inline void init(ulong size_arg, uint idx_arg, ulong increment_arg)
260
increment = increment_arg;
268
ulong query_cache_size, query_cache_limit;
270
ulong free_memory, queries_in_cache, hits, inserts, refused,
271
free_memory_blocks, total_blocks, lowmem_prunes;
276
my_thread_id m_cache_lock_thread_id;
278
pthread_cond_t COND_cache_status_changed;
279
enum Cache_lock_status { UNLOCKED, LOCKED_NO_WAIT, LOCKED };
280
Cache_lock_status m_cache_lock_status;
282
void free_query_internal(Query_cache_block *point);
283
void invalidate_table_internal(THD *thd, uchar *key, uint32 key_length);
287
The following mutex is locked when searching or changing global
288
query, tables lists or hashes. When we are operating inside the
289
query structure we locked an internal query block mutex.
290
LOCK SEQUENCE (to prevent deadlocks):
291
1. structure_guard_mutex
292
2. query block (for operation inside query (query block/results))
294
Thread doing cache flush releases the mutex once it sets
295
m_cache_status flag, so other threads may bypass the cache as
296
if it is disabled, not waiting for reset to finish. The exception
297
is other threads that were going to do cache flush---they'll wait
298
till the end of a flush operation.
300
pthread_mutex_t structure_guard_mutex;
301
uchar *cache; // cache memory
302
Query_cache_block *first_block; // physical location block list
303
Query_cache_block *queries_blocks; // query list (LIFO)
304
Query_cache_block *tables_blocks;
306
Query_cache_memory_bin *bins; // free block lists
307
Query_cache_memory_bin_step *steps; // bins spacing info
308
HASH queries, tables;
310
ulong min_allocation_unit, min_result_data_size;
311
uint def_query_hash_size, def_table_hash_size;
313
uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
317
/* Exclude/include from cyclic double linked list */
318
static void double_linked_list_exclude(Query_cache_block *point,
319
Query_cache_block **list_pointer);
320
static void double_linked_list_simple_include(Query_cache_block *point,
323
static void double_linked_list_join(Query_cache_block *head_tail,
324
Query_cache_block *tail_head);
326
/* Table key generation */
327
static uint filename_2_table_key (char *key, const char *filename,
330
/* The following functions require that structure_guard_mutex is locked */
332
my_bool free_old_query();
333
void free_query(Query_cache_block *point);
334
my_bool allocate_data_chain(Query_cache_block **result_block,
336
Query_cache_block *query_block,
337
my_bool first_block);
338
void invalidate_table(THD *thd, TABLE_LIST *table);
339
void invalidate_table(THD *thd, TABLE *table);
340
void invalidate_table(THD *thd, uchar *key, uint32 key_length);
341
void invalidate_table(THD *thd, Query_cache_block *table_block);
342
void invalidate_query_block_list(THD *thd,
343
Query_cache_block_table *list_root);
346
register_tables_from_list(TABLE_LIST *tables_used,
347
TABLE_COUNTER_TYPE counter,
348
Query_cache_block_table *block_table);
349
my_bool register_all_tables(Query_cache_block *block,
350
TABLE_LIST *tables_used,
351
TABLE_COUNTER_TYPE tables);
352
my_bool insert_table(uint key_len, char *key,
353
Query_cache_block_table *node,
354
uint32 db_length, uint8 cache_type,
355
qc_engine_callback callback,
356
ulonglong engine_data);
357
void unlink_table(Query_cache_block_table *node);
358
Query_cache_block *get_free_block (ulong len, my_bool not_less,
360
void free_memory_block(Query_cache_block *point);
361
void split_block(Query_cache_block *block, ulong len);
362
Query_cache_block *join_free_blocks(Query_cache_block *first_block,
363
Query_cache_block *block_in_list);
364
my_bool append_next_free_block(Query_cache_block *block,
366
void exclude_from_free_memory_list(Query_cache_block *free_block);
367
void insert_into_free_memory_list(Query_cache_block *new_block);
368
my_bool move_by_type(uchar **border, Query_cache_block **before,
369
ulong *gap, Query_cache_block *i);
370
uint find_bin(ulong size);
371
void move_to_query_list_end(Query_cache_block *block);
372
void insert_into_free_memory_sorted_list(Query_cache_block *new_block,
373
Query_cache_block **list);
375
void relink(Query_cache_block *oblock,
376
Query_cache_block *nblock,
377
Query_cache_block *next,
378
Query_cache_block *prev,
379
Query_cache_block *pnext,
380
Query_cache_block *pprev);
381
my_bool join_results(ulong join_limit);
384
Following function control structure_guard_mutex
385
by themself or don't need structure_guard_mutex
388
void make_disabled();
390
Query_cache_block *write_block_data(ulong data_len, uchar* data,
392
Query_cache_block::block_type type,
393
TABLE_COUNTER_TYPE ntab = 0);
394
my_bool append_result_data(Query_cache_block **result,
395
ulong data_len, uchar* data,
396
Query_cache_block *parent);
397
my_bool write_result_data(Query_cache_block **result,
398
ulong data_len, uchar* data,
399
Query_cache_block *parent,
400
Query_cache_block::block_type
401
type=Query_cache_block::RESULT);
402
inline ulong get_min_first_result_data_size();
403
inline ulong get_min_append_result_data_size();
404
Query_cache_block *allocate_block(ulong len, my_bool not_less,
407
If query is cacheable return number tables in query
408
(query without tables not cached)
410
TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query,
411
LEX *lex, TABLE_LIST *tables_used,
413
TABLE_COUNTER_TYPE process_and_count_tables(THD *thd,
414
TABLE_LIST *tables_used,
417
static my_bool ask_handler_allowance(THD *thd, TABLE_LIST *tables_used);
420
Query_cache(ulong query_cache_limit = ULONG_MAX,
421
ulong min_allocation_unit = QUERY_CACHE_MIN_ALLOCATION_UNIT,
422
ulong min_result_data_size = QUERY_CACHE_MIN_RESULT_DATA_SIZE,
423
uint def_query_hash_size = QUERY_CACHE_DEF_QUERY_HASH_SIZE,
424
uint def_table_hash_size = QUERY_CACHE_DEF_TABLE_HASH_SIZE);
426
/* initialize cache (mutex) */
428
/* resize query cache (return real query size, 0 if disabled) */
429
ulong resize(ulong query_cache_size);
430
/* set limit on result size */
431
inline void result_size_limit(ulong limit){query_cache_limit=limit;}
432
/* set minimal result data allocation unit size */
433
ulong set_min_res_unit(ulong size);
435
/* register query in cache */
436
void store_query(THD *thd, TABLE_LIST *used_tables);
439
Check if the query is in the cache and if this is true send the
442
int send_result_to_client(THD *thd, char *query, uint query_length);
444
/* Remove all queries that uses any of the listed following tables */
445
void invalidate(THD* thd, TABLE_LIST *tables_used,
446
my_bool using_transactions);
447
void invalidate(CHANGED_TABLE_LIST *tables_used);
448
void invalidate_locked_for_write(TABLE_LIST *tables_used);
449
void invalidate(THD* thd, TABLE *table, my_bool using_transactions);
450
void invalidate(THD *thd, const char *key, uint32 key_length,
451
my_bool using_transactions);
453
/* Remove all queries that uses any of the tables in following database */
454
void invalidate(char *db);
456
/* Remove all queries that uses any of the listed following table */
457
void invalidate_by_MyISAM_filename(const char *filename);
460
void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT,
461
uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
465
friend void query_cache_init_query(NET *net);
466
friend void query_cache_insert(NET *net, const char *packet, ulong length);
467
friend void query_cache_end_of_result(THD *thd);
468
friend void query_cache_abort(NET *net);
471
The following functions are only used when debugging
472
We don't protect these with ifndef DBUG_OFF to not have to recompile
473
everything if we want to add checks of the cache at some places.
475
void wreck(uint line, const char *message);
480
my_bool check_integrity(bool not_locked);
481
my_bool in_list(Query_cache_block * root, Query_cache_block * point,
483
my_bool in_table_list(Query_cache_block_table * root,
484
Query_cache_block_table * point,
486
my_bool in_blocks(Query_cache_block * point);
488
bool try_lock(bool use_timeout= FALSE);
490
void lock_and_suspend(void);
494
extern Query_cache query_cache;
495
extern TYPELIB query_cache_type_typelib;
496
void query_cache_init_query(NET *net);
497
void query_cache_insert(NET *net, const char *packet, ulong length);
498
void query_cache_end_of_result(THD *thd);
499
void query_cache_abort(NET *net);