1/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
2 Copyright (c) 2010, 2017, MariaDB Corporation
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software Foundation,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
16
17/*
18 Description of the query cache:
19
201. Query_cache object consists of
21 - query cache memory pool (cache)
22 - queries hash (queries)
23 - tables hash (tables)
24 - list of blocks ordered as they allocated in memory
25(first_block)
26 - list of queries block (queries_blocks)
27 - list of used tables (tables_blocks)
28
292. Query cache memory pool (cache) consists of
30 - table of steps of memory bins allocation
31 - table of free memory bins
32 - blocks of memory
33
343. Memory blocks
35
36Every memory block has the following structure:
37
38+----------------------------------------------------------+
39| Block header (Query_cache_block structure) |
40+----------------------------------------------------------+
41|Table of database table lists (used for queries & tables) |
42+----------------------------------------------------------+
43| Type depended header |
44|(Query_cache_query, Query_cache_table, Query_cache_result)|
45+----------------------------------------------------------+
46| Data ... |
47+----------------------------------------------------------+
48
49Block header consists of:
50- type:
51 FREE Free memory block
52 QUERY Query block
53 RESULT Ready to send result
54 RES_CONT Result's continuation
55 RES_BEG First block of results, that is not yet complete,
56 written to cache
57 RES_INCOMPLETE Allocated for results data block
58 TABLE Block with database table description
59 INCOMPLETE The destroyed block
60- length of block (length)
61- length of data & headers (used)
62- physical list links (pnext/pprev) - used for the list of
63 blocks ordered as they are allocated in physical memory
64- logical list links (next/prev) - used for queries block list, tables block
65 list, free memory block lists and list of results block in query
66- number of elements in table of database table list (n_tables)
67
684. Query & results blocks
69
70Query stored in cache consists of following blocks:
71
72more more
73recent+-------------+ old
74<-----|Query block 1|------> double linked list of queries block
75 prev | | next
76 +-------------+
77 <-| table 0 |-> (see "Table of database table lists" description)
78 <-| table 1 |->
79 | ... | +--------------------------+
80 +-------------+ +-------------------------+ |
81NET | | | V V |
82struct| | +-+------------+ +------------+ |
83<-----|query header |----->|Result block|-->|Result block|-+ doublelinked
84writer| |result| |<--| | list of results
85 +-------------+ +------------+ +------------+
86 |charset | +------------+ +------------+ no table of dbtables
87 |encoding + | | result | | result |
88 |query text |<-----| header | | header |------+
89 +-------------+parent| | | |parent|
90 ^ +------------+ +------------+ |
91 | |result data | |result data | |
92 | +------------+ +------------+ |
93 +---------------------------------------------------+
94
95First query is registered. During the registration query block is
96allocated. This query block is included in query hash and is linked
97with appropriate database tables lists (if there is no appropriate
98list exists it will be created).
99
100Later when query has performed results is written into the result blocks.
101A result block cannot be smaller then QUERY_CACHE_MIN_RESULT_DATA_SIZE.
102
103When new result is written to cache it is appended to the last result
104block, if no more free space left in the last block, new block is
105allocated.
106
1075. Table of database table lists.
108
109For quick invalidation of queries all query are linked in lists on used
110database tables basis (when table will be changed (insert/delete/...)
111this queries will be removed from cache).
112
113Root of such list is table block:
114
115 +------------+ list of used tables (used while invalidation of
116<----| Table |-----> whole database)
117 prev| block |next +-----------+
118 | | +-----------+ |Query block|
119 | | |Query block| +-----------+
120 +------------+ +-----------+ | ... |
121 +->| table 0 |------>|table 0 |----->| table N |---+
122 |+-| |<------| |<-----| |<-+|
123 || +------------+ | ... | | ... | ||
124 || |table header| +-----------+ +-----------+ ||
125 || +------------+ | ... | | ... | ||
126 || |db name + | +-----------+ +-----------+ ||
127 || |table name | ||
128 || +------------+ ||
129 |+--------------------------------------------------------+|
130 +----------------------------------------------------------+
131
132Table block is included into the tables hash (tables).
133
1346. Free blocks, free blocks bins & steps of freeblock bins.
135
136When we just started only one free memory block existed. All query
137cache memory (that will be used for block allocation) were
138containing in this block.
139When a new block is allocated we find most suitable memory block
140(minimal of >= required size). If such a block can not be found, we try
141to find max block < required size (if we allocate block for results).
142If there is no free memory, oldest query is removed from cache, and then
143we try to allocate memory. Last step should be repeated until we find
144suitable block or until there is no unlocked query found.
145
146If the block is found and its length more then we need, it should be
147split into 2 blocks.
148New blocks cannot be smaller then min_allocation_unit_bytes.
149
150When a block becomes free, its neighbor-blocks should be tested and if
151there are free blocks among them, they should be joined into one block.
152
153Free memory blocks are stored in bins according to their sizes.
154The bins are stored in size-descending order.
155These bins are distributed (by size) approximately logarithmically.
156
157First bin (number 0) stores free blocks with
158size <= query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2.
159It is first (number 0) step.
160On the next step distributed (1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
161QUERY_CACHE_MEM_BIN_PARTS_MUL bins. This bins allocated in interval from
162query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 to
163query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 >>
164QUERY_CACHE_MEM_BIN_STEP_PWR2
165...
166On each step interval decreases in 2 power of
167QUERY_CACHE_MEM_BIN_STEP_PWR2
168times, number of bins (that distributed on this step) increases. If on
169the previous step there were N bins distributed , on the current there
170would be distributed
171(N + QUERY_CACHE_MEM_BIN_PARTS_INC) * QUERY_CACHE_MEM_BIN_PARTS_MUL
172bins.
173Last distributed bin stores blocks with size near min_allocation_unit
174bytes.
175
176For example:
177 query_cache_size>>QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2 = 100,
178 min_allocation_unit = 17,
179 QUERY_CACHE_MEM_BIN_STEP_PWR2 = 1,
180 QUERY_CACHE_MEM_BIN_PARTS_INC = 1,
181 QUERY_CACHE_MEM_BIN_PARTS_MUL = 1
182 (in followed picture showed right (low) bound of bin):
183
184 | 100>>1 50>>1 |25>>1|
185 | | | | | |
186 | 100 75 50 41 33 25 21 18 15| 12 | - bins right (low) bounds
187
188 |\---/\-----/\--------/\--------|---/ |
189 | 0 1 2 3 | | - steps
190 \-----------------------------/ \---/
191 bins that we store in cache this bin showed for example only
192
193
194Calculation of steps/bins distribution is performed only when query cache
195is resized.
196
197When we need to find appropriate bin, first we should find appropriate
198step, then we should calculate number of bins that are using data
199stored in Query_cache_memory_bin_step structure.
200
201Free memory blocks are sorted in bins in lists with size-ascending order
202(more small blocks needed frequently then bigger one).
203
2047. Packing cache.
205
206Query cache packing is divided into two operation:
207 - pack_cache
208 - join_results
209
210pack_cache moved all blocks to "top" of cache and create one block of free
211space at the "bottom":
212
213 before pack_cache after pack_cache
214 +-------------+ +-------------+
215 | query 1 | | query 1 |
216 +-------------+ +-------------+
217 | table 1 | | table 1 |
218 +-------------+ +-------------+
219 | results 1.1 | | results 1.1 |
220 +-------------+ +-------------+
221 | free | | query 2 |
222 +-------------+ +-------------+
223 | query 2 | | table 2 |
224 +-------------+ ---> +-------------+
225 | table 2 | | results 1.2 |
226 +-------------+ +-------------+
227 | results 1.2 | | results 2 |
228 +-------------+ +-------------+
229 | free | | free |
230 +-------------+ | |
231 | results 2 | | |
232 +-------------+ | |
233 | free | | |
234 +-------------+ +-------------+
235
236pack_cache scan blocks in physical address order and move every non-free
237block "higher".
238
239pack_cach remove every free block it finds. The length of the deleted block
240is accumulated to the "gap". All non free blocks should be shifted with the
241"gap" step.
242
243join_results scans all complete queries. If the results of query are not
244stored in the same block, join_results tries to move results so, that they
245are stored in one block.
246
247 before join_results after join_results
248 +-------------+ +-------------+
249 | query 1 | | query 1 |
250 +-------------+ +-------------+
251 | table 1 | | table 1 |
252 +-------------+ +-------------+
253 | results 1.1 | | free |
254 +-------------+ +-------------+
255 | query 2 | | query 2 |
256 +-------------+ +-------------+
257 | table 2 | | table 2 |
258 +-------------+ ---> +-------------+
259 | results 1.2 | | free |
260 +-------------+ +-------------+
261 | results 2 | | results 2 |
262 +-------------+ +-------------+
263 | free | | results 1 |
264 | | | |
265 | | +-------------+
266 | | | free |
267 | | | |
268 +-------------+ +-------------+
269
270If join_results allocated new block(s) then we need call pack_cache again.
271
2727. Interface
273The query cache interfaces with the rest of the server code through 7
274functions:
275 1. Query_cache::send_result_to_client
276 - Called before parsing and used to match a statement with the stored
277 queries hash.
278 If a match is found the cached result set is sent through repeated
279 calls to net_real_write. (note: calling thread doesn't have a regis-
280 tered result set writer: thd->net.query_cache_query=0)
281 2. Query_cache::store_query
282 - Called just before handle_select() and is used to register a result
283 set writer to the statement currently being processed
284 (thd->net.query_cache_query).
285 3. query_cache_insert
286 - Called from net_real_write to append a result set to a cached query
287 if (and only if) this query has a registered result set writer
288 (thd->net.query_cache_query).
289 4. Query_cache::invalidate
290 Query_cache::invalidate_locked_for_write
291 - Called from various places to invalidate query cache based on data-
292 base, table and myisam file name. During an on going invalidation
293 the query cache is temporarily disabled.
294 5. Query_cache::flush
295 - Used when a RESET QUERY CACHE is issued. This clears the entire
296 cache block by block.
297 6. Query_cache::resize
298 - Used to change the available memory used by the query cache. This
299 will also invalidate the entrie query cache in one free operation.
300 7. Query_cache::pack
301 - Used when a FLUSH QUERY CACHE is issued. This changes the order of
302 the used memory blocks in physical memory order and move all avail-
303 able memory to the 'bottom' of the memory.
304
305
306TODO list:
307
308 - Delayed till after-parsing qache answer (for column rights processing)
309 - Optimize cache resizing
310 - if new_size < old_size then pack & shrink
311 - if new_size > old_size copy cached query to new cache
312 - Move MRG_MYISAM table type processing to handlers, something like:
313 tables_used->table->file->register_used_filenames(callback,
314 first_argument);
315 - QC improvement suggested by Monty:
316 - Add a counter in open_table() for how many MERGE (ISAM or MyISAM)
317 tables are cached in the table cache.
318 (This will be trivial when we have the new table cache in place I
319 have been working on)
320 - After this we can add the following test around the for loop in
321 is_cacheable::
322
323 if (thd->temp_tables || global_merge_table_count)
324
325 - Another option would be to set thd->lex->safe_to_cache_query to 0
326 in 'get_lock_data' if any of the tables was a tmp table or a
327 MRG_ISAM table.
328 (This could be done with almost no speed penalty)
329*/
330
331#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
332#if defined(DBUG_OFF) && defined(HAVE_MADVISE)
333#include <sys/mman.h>
334#endif
335#include "sql_priv.h"
336#include "sql_basic_types.h"
337#include "sql_cache.h"
338#include "sql_parse.h" // check_table_access
339#include "tztime.h" // struct Time_zone
340#include "sql_acl.h" // SELECT_ACL
341#include "sql_base.h" // TMP_TABLE_KEY_EXTRA
342#include "debug_sync.h" // DEBUG_SYNC
343#include "sql_table.h"
344#ifdef HAVE_QUERY_CACHE
345#include <m_ctype.h>
346#include <my_dir.h>
347#include <hash.h>
348#include "../storage/myisammrg/ha_myisammrg.h"
349#include "../storage/myisammrg/myrg_def.h"
350#include "probes_mysql.h"
351#include "transaction.h"
352#include "strfunc.h"
353
354const uchar *query_state_map;
355
356#ifdef EMBEDDED_LIBRARY
357#include "emb_qcache.h"
358#endif
359
360#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
361#define RW_WLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock %p",(M))); \
362 if (!mysql_rwlock_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")); \
363 else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
364#define RW_RLOCK(M) {DBUG_PRINT("lock", ("rwlock rlock %p",(M))); \
365 if (!mysql_rwlock_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")); \
366 else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); }
367#define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock unlock %p",(M))); \
368 if (!mysql_rwlock_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")); \
369 else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); }
370#define BLOCK_LOCK_WR(B) {DBUG_PRINT("lock", ("%d LOCK_WR %p",\
371 __LINE__,(B))); \
372 B->query()->lock_writing();}
373#define BLOCK_LOCK_RD(B) {DBUG_PRINT("lock", ("%d LOCK_RD %p",\
374 __LINE__,(B))); \
375 B->query()->lock_reading();}
376#define BLOCK_UNLOCK_WR(B) { \
377 DBUG_PRINT("lock", ("%d UNLOCK_WR %p",\
378 __LINE__,(B)));B->query()->unlock_writing();}
379#define BLOCK_UNLOCK_RD(B) { \
380 DBUG_PRINT("lock", ("%d UNLOCK_RD %p",\
381 __LINE__,(B)));B->query()->unlock_reading();}
382#define DUMP(C) DBUG_EXECUTE("qcache", {\
383 (C)->cache_dump(); (C)->queries_dump();(C)->tables_dump();})
384#else
385#define RW_WLOCK(M) mysql_rwlock_wrlock(M)
386#define RW_RLOCK(M) mysql_rwlock_rdlock(M)
387#define RW_UNLOCK(M) mysql_rwlock_unlock(M)
388#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
389#define BLOCK_LOCK_RD(B) B->query()->lock_reading()
390#define BLOCK_UNLOCK_WR(B) B->query()->unlock_writing()
391#define BLOCK_UNLOCK_RD(B) B->query()->unlock_reading()
392#define DUMP(C)
393#endif
394
395
396/**
397 Macro that executes the requested action at a synchronization point
398 only if the thread has a associated THD session.
399*/
400#if defined(ENABLED_DEBUG_SYNC)
401#define QC_DEBUG_SYNC(name) \
402 do { \
403 THD *thd_tmp= current_thd; \
404 if (thd_tmp) \
405 DEBUG_SYNC(thd_tmp, name); \
406 } while (0)
407#else
408#define QC_DEBUG_SYNC(name)
409#endif
410
411
412/**
413 Thread state to be used when the query cache lock needs to be acquired.
414 Sets the thread state name in the constructor, resets on destructor.
415*/
416
417struct Query_cache_wait_state
418{
419 THD *m_thd;
420 PSI_stage_info m_old_stage;
421 const char *m_func;
422 const char *m_file;
423 int m_line;
424
425 Query_cache_wait_state(THD *thd, const char *func,
426 const char *file, unsigned int line)
427 : m_thd(thd),
428 m_old_stage(),
429 m_func(func), m_file(file), m_line(line)
430 {
431 if (m_thd)
432 set_thd_stage_info(m_thd,
433 &stage_waiting_for_query_cache_lock,
434 &m_old_stage,
435 m_func, m_file, m_line);
436 }
437
438 ~Query_cache_wait_state()
439 {
440 if (m_thd)
441 set_thd_stage_info(m_thd, &m_old_stage, NULL, m_func, m_file, m_line);
442 }
443};
444
445
446/*
447 Check if character is a white space.
448*/
449
450inline bool is_white_space(char c)
451{
452 return (query_state_map[(uint) ((uchar) c)] == MY_LEX_SKIP);
453}
454
455
456/**
457 Generate a query_string without query comments or duplicated space
458
459 @param new_query New query without 'fluff' is stored here
460 @param query Original query
461 @param query_length Length of original query
462 @param additional_length Extra space for query cache we need to allocate
463 in new_query buffer.
464
465 Note:
466 If there is no space to allocate new_query, we will put original query
467 into new_query.
468*/
469
470static void make_base_query(String *new_query,
471 const char *query, size_t query_length,
472 size_t additional_length)
473{
474 char *buffer;
475 const char *query_end, *last_space;
476
477 /* The following is guaranteed by the query_cache interface */
478 DBUG_ASSERT(query[query_length] == 0);
479 DBUG_ASSERT(!is_white_space(query[0]));
480 /* We do not support UCS2, UTF16, UTF32 as a client character set */
481 DBUG_ASSERT(current_thd->variables.character_set_client->mbminlen == 1);
482
483 new_query->length(0); // Don't copy anything from old buffer
484 if (new_query->realloc(query_length + additional_length))
485 {
486 /*
487 We could not allocate the query. Use original query for
488 the query cache; Better than nothing....
489 */
490 new_query->set(query, query_length, system_charset_info);
491 return;
492 }
493
494 buffer= (char*) new_query->ptr(); // Store base query here
495 query_end= query + query_length;
496 last_space= 0; // No space found yet
497
498 while (query < query_end)
499 {
500 char current = *(query++);
501 switch (current) {
502 case '\'':
503 case '`':
504 case '"':
505 *(buffer++)= current; // copy first quote
506 while (query < query_end)
507 {
508 *(buffer++)= *query;
509 if (*(query++) == current) // found pair quote
510 break;
511 }
512 continue; // Continue with next symbol
513 case '/': // Start of comment ?
514 /*
515 Comment of format /#!number #/ or /#M!number #/, must be skipped.
516 These may include '"' and other comments, but it should
517 be safe to parse the content as a normal string.
518 */
519 if (query[0] != '*' || query[1] == '!' ||
520 (query[1] == 'M' && query[2] == '!'))
521 break;
522
523 query++; // skip "/"
524 while (++query < query_end)
525 {
526 if (query[0] == '*' && query[1] == '/')
527 {
528 query+= 2;
529 goto insert_space;
530 }
531 }
532 continue; // Will end outer loop
533 case '-':
534 if (*query != '-' || !is_white_space(query[1])) // Not a comment
535 break;
536 query++; // skip second "-", and go to search of "\n"
537 /* fall through */
538 case '#':
539 while (query < query_end)
540 {
541 if (*(query++) == '\n')
542 goto insert_space;
543 }
544 continue; // Will end outer loop
545 default:
546 if (is_white_space(current))
547 goto insert_space;
548 break;
549 }
550 *(buffer++)= current;
551 continue;
552
553insert_space:
554 if (buffer != last_space)
555 {
556 *(buffer++)= ' ';
557 last_space= buffer;
558 }
559 }
560 if (buffer == last_space)
561 buffer--; // Remove the last space
562 *buffer= 0; // End zero after query
563 new_query->length((size_t) (buffer - new_query->ptr()));
564
565 /* Copy db_length */
566 memcpy(buffer+1, query_end+1, QUERY_CACHE_DB_LENGTH_SIZE);
567}
568
569
570/**
571 Check and change local variable if global one is switched
572
573 @param thd thread handle
574*/
575
576void inline fix_local_query_cache_mode(THD *thd)
577{
578 if (global_system_variables.query_cache_type == 0)
579 thd->variables.query_cache_type= 0;
580}
581
582
583/**
584 Serialize access to the query cache.
585 If the lock cannot be granted the thread hangs in a conditional wait which
586 is signalled on each unlock.
587
588 The lock attempt will also fail without wait if lock_and_suspend() is in
589 effect by another thread. This enables a quick path in execution to skip waits
590 when the outcome is known.
591
592 @param mode TIMEOUT the lock can abort because of a timeout
593 TRY the lock can abort because it is locked now
594 WAIT wait for lock (default)
595
596 @note mode is optional and default value is WAIT.
597
598 @return
599 @retval FALSE An exclusive lock was taken
600 @retval TRUE The locking attempt failed
601*/
602
603bool Query_cache::try_lock(THD *thd, Cache_try_lock_mode mode)
604{
605 bool interrupt= TRUE;
606 Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
607 DBUG_ENTER("Query_cache::try_lock");
608
609 mysql_mutex_lock(&structure_guard_mutex);
610 DBUG_EXECUTE_IF("status_wait_query_cache_mutex_sleep", { sleep(5); });
611 if (m_cache_status == DISABLED)
612 {
613 mysql_mutex_unlock(&structure_guard_mutex);
614 DBUG_RETURN(TRUE);
615 }
616 m_requests_in_progress++;
617 fix_local_query_cache_mode(thd);
618
619 while (1)
620 {
621 if (m_cache_lock_status == Query_cache::UNLOCKED)
622 {
623 m_cache_lock_status= Query_cache::LOCKED;
624#ifndef DBUG_OFF
625 m_cache_lock_thread_id= thd->thread_id;
626#endif
627 interrupt= FALSE;
628 break;
629 }
630 else if (m_cache_lock_status == Query_cache::LOCKED_NO_WAIT)
631 {
632 /*
633 If query cache is protected by a LOCKED_NO_WAIT lock this thread
634 should avoid using the query cache as it is being evicted.
635 */
636 break;
637 }
638 else
639 {
640 DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED);
641 /*
642 To prevent send_result_to_client() and query_cache_insert() from
643 blocking execution for too long a timeout is put on the lock.
644 */
645 if (mode == WAIT)
646 {
647 mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
648 }
649 else if (mode == TIMEOUT)
650 {
651 struct timespec waittime;
652 set_timespec_nsec(waittime,50000000UL); /* Wait for 50 msec */
653 int res= mysql_cond_timedwait(&COND_cache_status_changed,
654 &structure_guard_mutex, &waittime);
655 if (res == ETIMEDOUT)
656 break;
657 }
658 else
659 {
660 /**
661 If we are here, then mode is == TRY and there was someone else using
662 the query cache. (m_cache_lock_status != Query_cache::UNLOCKED).
663 Signal that we didn't get a lock.
664 */
665 DBUG_ASSERT(m_requests_in_progress > 1);
666 DBUG_ASSERT(mode == TRY);
667 break;
668 }
669 }
670 }
671 if (interrupt)
672 m_requests_in_progress--;
673 mysql_mutex_unlock(&structure_guard_mutex);
674
675 DBUG_RETURN(interrupt);
676}
677
678
679/**
680 Serialize access to the query cache.
681 If the lock cannot be granted the thread hangs in a conditional wait which
682 is signalled on each unlock.
683
684 This method also suspends the query cache so that other threads attempting to
685 lock the cache with try_lock() will fail directly without waiting.
686
687 It is used by all methods which flushes or destroys the whole cache.
688 */
689
690void Query_cache::lock_and_suspend(void)
691{
692 THD *thd= current_thd;
693 Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
694 DBUG_ENTER("Query_cache::lock_and_suspend");
695
696 mysql_mutex_lock(&structure_guard_mutex);
697 m_requests_in_progress++;
698 while (m_cache_lock_status != Query_cache::UNLOCKED)
699 mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
700 m_cache_lock_status= Query_cache::LOCKED_NO_WAIT;
701#ifndef DBUG_OFF
702 /* Here thd may not be set during shutdown */
703 if (thd)
704 m_cache_lock_thread_id= thd->thread_id;
705#endif
706 /* Wake up everybody, a whole cache flush is starting! */
707 mysql_cond_broadcast(&COND_cache_status_changed);
708 mysql_mutex_unlock(&structure_guard_mutex);
709
710 DBUG_VOID_RETURN;
711}
712
713/**
714 Serialize access to the query cache.
715 If the lock cannot be granted the thread hangs in a conditional wait which
716 is signalled on each unlock.
717
718 It is used by all methods which invalidates one or more tables.
719 */
720
721void Query_cache::lock(THD *thd)
722{
723 Query_cache_wait_state wait_state(thd, __func__, __FILE__, __LINE__);
724 DBUG_ENTER("Query_cache::lock");
725
726 mysql_mutex_lock(&structure_guard_mutex);
727 m_requests_in_progress++;
728 fix_local_query_cache_mode(thd);
729 while (m_cache_lock_status != Query_cache::UNLOCKED)
730 mysql_cond_wait(&COND_cache_status_changed, &structure_guard_mutex);
731 m_cache_lock_status= Query_cache::LOCKED;
732#ifndef DBUG_OFF
733 m_cache_lock_thread_id= thd->thread_id;
734#endif
735 mysql_mutex_unlock(&structure_guard_mutex);
736
737 DBUG_VOID_RETURN;
738}
739
740
741/**
742 Set the query cache to UNLOCKED and signal waiting threads.
743*/
744
745void Query_cache::unlock(void)
746{
747 DBUG_ENTER("Query_cache::unlock");
748 mysql_mutex_lock(&structure_guard_mutex);
749#ifndef DBUG_OFF
750 /* Thd may not be set in resize() at mysqld start */
751 THD *thd= current_thd;
752 if (thd)
753 DBUG_ASSERT(m_cache_lock_thread_id == thd->thread_id);
754#endif
755 DBUG_ASSERT(m_cache_lock_status == Query_cache::LOCKED ||
756 m_cache_lock_status == Query_cache::LOCKED_NO_WAIT);
757 m_cache_lock_status= Query_cache::UNLOCKED;
758 DBUG_PRINT("Query_cache",("Sending signal"));
759 mysql_cond_signal(&COND_cache_status_changed);
760 DBUG_ASSERT(m_requests_in_progress > 0);
761 m_requests_in_progress--;
762 if (m_requests_in_progress == 0 && m_cache_status == DISABLE_REQUEST)
763 {
764 /* No clients => just free query cache */
765 free_cache();
766 m_cache_status= DISABLED;
767 }
768 mysql_mutex_unlock(&structure_guard_mutex);
769 DBUG_VOID_RETURN;
770}
771
772
773/**
774 Helper function for determine if a SELECT statement has a SQL_NO_CACHE
775 directive.
776
777 @param sql A pointer to the first white space character after SELECT
778
779 @return
780 @retval TRUE The character string contains SQL_NO_CACHE
781 @retval FALSE No directive found.
782*/
783
784static bool has_no_cache_directive(const char *sql)
785{
786 while (is_white_space(*sql))
787 sql++;
788
789 if (my_toupper(system_charset_info, sql[0]) == 'S' &&
790 my_toupper(system_charset_info, sql[1]) == 'Q' &&
791 my_toupper(system_charset_info, sql[2]) == 'L' &&
792 my_toupper(system_charset_info, sql[3]) == '_' &&
793 my_toupper(system_charset_info, sql[4]) == 'N' &&
794 my_toupper(system_charset_info, sql[5]) == 'O' &&
795 my_toupper(system_charset_info, sql[6]) == '_' &&
796 my_toupper(system_charset_info, sql[7]) == 'C' &&
797 my_toupper(system_charset_info, sql[8]) == 'A' &&
798 my_toupper(system_charset_info, sql[9]) == 'C' &&
799 my_toupper(system_charset_info, sql[10]) == 'H' &&
800 my_toupper(system_charset_info, sql[11]) == 'E' &&
801 my_isspace(system_charset_info, sql[12]))
802 return TRUE;
803
804 return FALSE;
805}
806
807
808/*****************************************************************************
809 Query_cache_block_table method(s)
810*****************************************************************************/
811
812inline Query_cache_block * Query_cache_block_table::block()
813{
814 return (Query_cache_block *)(((uchar*)this) -
815 ALIGN_SIZE(sizeof(Query_cache_block_table)*n) -
816 ALIGN_SIZE(sizeof(Query_cache_block)));
817}
818
819/*****************************************************************************
820 Query_cache_block method(s)
821*****************************************************************************/
822
823void Query_cache_block::init(size_t block_length)
824{
825 DBUG_ENTER("Query_cache_block::init");
826 DBUG_PRINT("qcache", ("init block: %p length: %zu", this,
827 block_length));
828 length = block_length;
829 used = 0;
830 type = Query_cache_block::FREE;
831 n_tables = 0;
832 DBUG_VOID_RETURN;
833}
834
835void Query_cache_block::destroy()
836{
837 DBUG_ENTER("Query_cache_block::destroy");
838 DBUG_PRINT("qcache", ("destroy block %p, type %d",
839 this, type));
840 type = INCOMPLETE;
841 DBUG_VOID_RETURN;
842}
843
844uint Query_cache_block::headers_len()
845{
846 return (ALIGN_SIZE(sizeof(Query_cache_block_table)*n_tables) +
847 ALIGN_SIZE(sizeof(Query_cache_block)));
848}
849
850uchar* Query_cache_block::data(void)
851{
852 return (uchar*)( ((uchar*)this) + headers_len() );
853}
854
855Query_cache_query * Query_cache_block::query()
856{
857#ifndef DBUG_OFF
858 if (type != QUERY)
859 query_cache.wreck(__LINE__, "incorrect block type");
860#endif
861 return (Query_cache_query *) data();
862}
863
864Query_cache_table * Query_cache_block::table()
865{
866#ifndef DBUG_OFF
867 if (type != TABLE)
868 query_cache.wreck(__LINE__, "incorrect block type");
869#endif
870 return (Query_cache_table *) data();
871}
872
873Query_cache_result * Query_cache_block::result()
874{
875#ifndef DBUG_OFF
876 if (type != RESULT && type != RES_CONT && type != RES_BEG &&
877 type != RES_INCOMPLETE)
878 query_cache.wreck(__LINE__, "incorrect block type");
879#endif
880 return (Query_cache_result *) data();
881}
882
883Query_cache_block_table * Query_cache_block::table(TABLE_COUNTER_TYPE n)
884{
885 return ((Query_cache_block_table *)
886 (((uchar*)this)+ALIGN_SIZE(sizeof(Query_cache_block)) +
887 n*sizeof(Query_cache_block_table)));
888}
889
890
891/*****************************************************************************
892 * Query_cache_table method(s)
893 *****************************************************************************/
894
895extern "C"
896{
897uchar *query_cache_table_get_key(const uchar *record, size_t *length,
898 my_bool not_used __attribute__((unused)))
899{
900 Query_cache_block* table_block = (Query_cache_block*) record;
901 *length = (table_block->used - table_block->headers_len() -
902 ALIGN_SIZE(sizeof(Query_cache_table)));
903 return (((uchar *) table_block->data()) +
904 ALIGN_SIZE(sizeof(Query_cache_table)));
905}
906}
907
908/*****************************************************************************
909 Query_cache_query methods
910*****************************************************************************/
911
912/*
913 Following methods work for block read/write locking only in this
914 particular case and in interaction with structure_guard_mutex.
915
916 Lock for write prevents any other locking. (exclusive use)
917 Lock for read prevents only locking for write.
918*/
919
920inline void Query_cache_query::lock_writing()
921{
922 RW_WLOCK(&lock);
923}
924
925
926/*
927 Needed for finding queries, that we may delete from cache.
928 We don't want to wait while block become unlocked. In addition,
929 block locking means that query is now used and we don't need to
930 remove it.
931*/
932
933bool Query_cache_query::try_lock_writing()
934{
935 DBUG_ENTER("Query_cache_block::try_lock_writing");
936 if (mysql_rwlock_trywrlock(&lock) != 0)
937 {
938 DBUG_PRINT("info", ("can't lock rwlock"));
939 DBUG_RETURN(0);
940 }
941 DBUG_PRINT("info", ("rwlock %p locked", &lock));
942 DBUG_RETURN(1);
943}
944
945
946inline void Query_cache_query::lock_reading()
947{
948 RW_RLOCK(&lock);
949}
950
951
952inline void Query_cache_query::unlock_writing()
953{
954 RW_UNLOCK(&lock);
955}
956
957
958inline void Query_cache_query::unlock_reading()
959{
960 RW_UNLOCK(&lock);
961}
962
963
964void Query_cache_query::init_n_lock()
965{
966 DBUG_ENTER("Query_cache_query::init_n_lock");
967 res=0; wri = 0; len = 0; ready= 0; hit_count = 0;
968 mysql_rwlock_init(key_rwlock_query_cache_query_lock, &lock);
969 lock_writing();
970 DBUG_PRINT("qcache", ("inited & locked query for block %p",
971 (uchar*) this -
972 ALIGN_SIZE(sizeof(Query_cache_block))));
973 DBUG_VOID_RETURN;
974}
975
976
977void Query_cache_query::unlock_n_destroy()
978{
979 DBUG_ENTER("Query_cache_query::unlock_n_destroy");
980 DBUG_PRINT("qcache", ("destroyed & unlocked query for block %p",
981 (uchar*) this -
982 ALIGN_SIZE(sizeof(Query_cache_block))));
983 /*
984 The following call is not needed on system where one can destroy an
985 active semaphore
986 */
987 this->unlock_writing();
988 mysql_rwlock_destroy(&lock);
989 DBUG_VOID_RETURN;
990}
991
992
993extern "C"
994{
995uchar *query_cache_query_get_key(const uchar *record, size_t *length,
996 my_bool not_used)
997{
998 Query_cache_block *query_block = (Query_cache_block*) record;
999 *length = (query_block->used - query_block->headers_len() -
1000 ALIGN_SIZE(sizeof(Query_cache_query)));
1001 return (((uchar *) query_block->data()) +
1002 ALIGN_SIZE(sizeof(Query_cache_query)));
1003}
1004}
1005
1006/*****************************************************************************
1007 Functions to store things into the query cache
1008*****************************************************************************/
1009
1010/*
1011 Note on double-check locking (DCL) usage.
1012
1013 Below, in query_cache_insert(), query_cache_abort() and
1014 Query_cache::end_of_result() we use what is called double-check
1015 locking (DCL) for Query_cache_tls::first_query_block.
1016 I.e. we test it first without a lock, and, if positive, test again
1017 under the lock.
1018
1019 This means that if we see 'first_query_block == 0' without a
1020 lock we will skip the operation. But this is safe here: when we
1021 started to cache a query, we called Query_cache::store_query(), and
1022 'first_query_block' was set to non-zero in this thread (and the
1023 thread always sees results of its memory operations, mutex or not).
1024 If later we see 'first_query_block == 0' without locking a
1025 mutex, that may only mean that some other thread have reset it by
1026 invalidating the query. Skipping the operation in this case is the
1027 right thing to do, as first_query_block won't get non-zero for
1028 this query again.
1029
1030 See also comments in Query_cache::store_query() and
1031 Query_cache::send_result_to_client().
1032
1033 NOTE, however, that double-check locking is not applicable in
1034 'invalidate' functions, as we may erroneously skip invalidation,
1035 because the thread doing invalidation may never see non-zero
1036 'first_query_block'.
1037*/
1038
1039
1040/**
1041 libmysql convenience wrapper to insert data into query cache.
1042*/
1043void query_cache_insert(void *thd_arg, const char *packet, size_t length,
1044 unsigned pkt_nr)
1045{
1046 THD *thd= (THD*) thd_arg;
1047
1048 /*
1049 Current_thd can be NULL when a new connection is immediately ended
1050 due to "Too many connections". thd->store_globals() has not been
1051 called at this time and hence set_current_thd(this) has not been
1052 called for this thread.
1053 */
1054
1055 if (unlikely(!thd))
1056 return;
1057
1058 query_cache.insert(thd, &thd->query_cache_tls,
1059 packet, (size_t)length,
1060 pkt_nr);
1061}
1062
1063
1064/**
1065 Insert the packet into the query cache.
1066*/
1067
1068void
1069Query_cache::insert(THD *thd, Query_cache_tls *query_cache_tls,
1070 const char *packet, size_t length,
1071 unsigned pkt_nr)
1072{
1073 DBUG_ENTER("Query_cache::insert");
1074
1075 /* First we check if query cache is disable without doing a mutex lock */
1076 if (is_disabled() || query_cache_tls->first_query_block == NULL)
1077 DBUG_VOID_RETURN;
1078
1079 QC_DEBUG_SYNC("wait_in_query_cache_insert");
1080
1081 /*
1082 Lock the cache with try_lock(). try_lock() will fail if
1083 cache was disabled between the above test and lock.
1084 */
1085 if (try_lock(thd, Query_cache::WAIT))
1086 DBUG_VOID_RETURN;
1087
1088 Query_cache_block *query_block = query_cache_tls->first_query_block;
1089 if (query_block == NULL)
1090 {
1091 /*
1092 We lost the writer and the currently processed query has been
1093 invalidated; there is nothing left to do.
1094 */
1095 unlock();
1096 DBUG_VOID_RETURN;
1097 }
1098 BLOCK_LOCK_WR(query_block);
1099 Query_cache_query *header= query_block->query();
1100 Query_cache_block *result= header->result();
1101
1102 DUMP(this);
1103 DBUG_PRINT("qcache", ("insert packet %zu bytes long",length));
1104
1105 /*
1106 On success, STRUCT_UNLOCK is done by append_result_data. Otherwise, we
1107 still need structure_guard_mutex to free the query, and therefore unlock
1108 it later in this function.
1109 */
1110 if (!append_result_data(&result, length, (uchar*) packet,
1111 query_block))
1112 {
1113 DBUG_PRINT("warning", ("Can't append data"));
1114 header->result(result);
1115 DBUG_PRINT("qcache", ("free query %p", query_block));
1116 // The following call will remove the lock on query_block
1117 query_cache.free_query(query_block);
1118 query_cache.refused++;
1119 // append_result_data no success => we need unlock
1120 unlock();
1121 DBUG_VOID_RETURN;
1122 }
1123
1124 header->result(result);
1125 header->last_pkt_nr= pkt_nr;
1126 BLOCK_UNLOCK_WR(query_block);
1127 DBUG_EXECUTE("check_querycache",check_integrity(0););
1128
1129 DBUG_VOID_RETURN;
1130}
1131
1132
1133void
1134Query_cache::abort(THD *thd, Query_cache_tls *query_cache_tls)
1135{
1136 DBUG_ENTER("query_cache_abort");
1137
1138 /* See the comment on double-check locking usage above. */
1139 if (is_disabled() || query_cache_tls->first_query_block == NULL)
1140 DBUG_VOID_RETURN;
1141
1142 if (try_lock(thd, Query_cache::WAIT))
1143 DBUG_VOID_RETURN;
1144
1145 /*
1146 While we were waiting another thread might have changed the status
1147 of the writer. Make sure the writer still exists before continue.
1148 */
1149 Query_cache_block *query_block= query_cache_tls->first_query_block;
1150 if (query_block)
1151 {
1152 THD_STAGE_INFO(thd, stage_storing_result_in_query_cache);
1153 DUMP(this);
1154 BLOCK_LOCK_WR(query_block);
1155 // The following call will remove the lock on query_block
1156 free_query(query_block);
1157 query_cache_tls->first_query_block= NULL;
1158 DBUG_EXECUTE("check_querycache", check_integrity(1););
1159 }
1160
1161 unlock();
1162
1163 DBUG_VOID_RETURN;
1164}
1165
1166
1167void Query_cache::end_of_result(THD *thd)
1168{
1169 Query_cache_block *query_block;
1170 Query_cache_tls *query_cache_tls= &thd->query_cache_tls;
1171 ulonglong limit_found_rows= thd->limit_found_rows;
1172 DBUG_ENTER("Query_cache::end_of_result");
1173
1174 /* See the comment on double-check locking usage above. */
1175 if (query_cache_tls->first_query_block == NULL)
1176 DBUG_VOID_RETURN;
1177
1178 /* Ensure that only complete results are cached. */
1179 DBUG_ASSERT(thd->get_stmt_da()->is_eof());
1180
1181 if (thd->killed)
1182 {
1183 query_cache_abort(thd, &thd->query_cache_tls);
1184 DBUG_VOID_RETURN;
1185 }
1186
1187#ifdef EMBEDDED_LIBRARY
1188 insert(thd, query_cache_tls, (char*)thd,
1189 emb_count_querycache_size(thd), 0);
1190#endif
1191
1192 if (try_lock(thd, Query_cache::WAIT))
1193 {
1194 if (is_disabled())
1195 query_cache_tls->first_query_block= NULL; // do not try again with QC
1196 DBUG_VOID_RETURN;
1197 }
1198
1199 query_block= query_cache_tls->first_query_block;
1200 if (query_block)
1201 {
1202 /*
1203 The writer is still present; finish last result block by chopping it to
1204 suitable size if needed and setting block type. Since this is the last
1205 block, the writer should be dropped.
1206 */
1207 THD_STAGE_INFO(thd, stage_storing_result_in_query_cache);
1208 DUMP(this);
1209 BLOCK_LOCK_WR(query_block);
1210 Query_cache_query *header= query_block->query();
1211 Query_cache_block *last_result_block;
1212 size_t allign_size;
1213 size_t len;
1214
1215 if (header->result() == 0)
1216 {
1217 DBUG_PRINT("error", ("End of data with no result blocks; "
1218 "Query '%s' removed from cache.", header->query()));
1219 /*
1220 Extra safety: empty result should not happen in the normal call
1221 to this function. In the release version that query should be ignored
1222 and removed from QC.
1223 */
1224 DBUG_ASSERT(0);
1225 free_query(query_block);
1226 unlock();
1227 DBUG_VOID_RETURN;
1228 }
1229 last_result_block= header->result()->prev;
1230 allign_size= ALIGN_SIZE(last_result_block->used);
1231 len= MY_MAX(query_cache.min_allocation_unit, allign_size);
1232 if (last_result_block->length >= query_cache.min_allocation_unit + len)
1233 query_cache.split_block(last_result_block,len);
1234
1235 header->found_rows(limit_found_rows);
1236 header->set_results_ready(); // signal for plugin
1237 header->result()->type= Query_cache_block::RESULT;
1238
1239 /* Drop the writer. */
1240 header->writer(0);
1241 query_cache_tls->first_query_block= NULL;
1242 BLOCK_UNLOCK_WR(query_block);
1243 DBUG_EXECUTE("check_querycache", check_integrity(1););
1244 }
1245
1246 unlock();
1247 DBUG_VOID_RETURN;
1248}
1249
1250void query_cache_invalidate_by_MyISAM_filename(const char *filename)
1251{
1252 query_cache.invalidate_by_MyISAM_filename(filename);
1253 DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
1254}
1255
1256
1257/*
1258 The following function forms part of the C plugin API
1259*/
1260extern "C"
1261void mysql_query_cache_invalidate4(THD *thd,
1262 const char *key, unsigned key_length,
1263 int using_trx)
1264{
1265 query_cache.invalidate(thd, key, (uint32) key_length, (my_bool) using_trx);
1266}
1267
1268
1269/*****************************************************************************
1270 Query_cache methods
1271*****************************************************************************/
1272
1273Query_cache::Query_cache(size_t query_cache_limit_arg,
1274 size_t min_allocation_unit_arg,
1275 size_t min_result_data_size_arg,
1276 uint def_query_hash_size_arg,
1277 uint def_table_hash_size_arg)
1278 :query_cache_size(0),
1279 query_cache_limit(query_cache_limit_arg),
1280 queries_in_cache(0), hits(0), inserts(0), refused(0),
1281 total_blocks(0), lowmem_prunes(0),
1282 m_cache_status(OK),
1283 min_allocation_unit(ALIGN_SIZE(min_allocation_unit_arg)),
1284 min_result_data_size(ALIGN_SIZE(min_result_data_size_arg)),
1285 def_query_hash_size(ALIGN_SIZE(def_query_hash_size_arg)),
1286 def_table_hash_size(ALIGN_SIZE(def_table_hash_size_arg)),
1287 initialized(0)
1288{
1289 size_t min_needed= (ALIGN_SIZE(sizeof(Query_cache_block)) +
1290 ALIGN_SIZE(sizeof(Query_cache_block_table)) +
1291 ALIGN_SIZE(sizeof(Query_cache_query)) + 3);
1292 set_if_bigger(min_allocation_unit,min_needed);
1293 this->min_allocation_unit= ALIGN_SIZE(min_allocation_unit);
1294 set_if_bigger(this->min_result_data_size,min_allocation_unit);
1295}
1296
1297
1298size_t Query_cache::resize(size_t query_cache_size_arg)
1299{
1300 size_t new_query_cache_size;
1301 DBUG_ENTER("Query_cache::resize");
1302 DBUG_PRINT("qcache", ("from %zu to %zu",query_cache_size,
1303 query_cache_size_arg));
1304 DBUG_ASSERT(initialized);
1305
1306 lock_and_suspend();
1307
1308 /*
1309 Wait for all readers and writers to exit. When the list of all queries
1310 is iterated over with a block level lock, we are done.
1311 */
1312 Query_cache_block *block= queries_blocks;
1313 if (block)
1314 {
1315 do
1316 {
1317 BLOCK_LOCK_WR(block);
1318 Query_cache_query *query= block->query();
1319 if (query->writer())
1320 {
1321 /*
1322 Drop the writer; this will cancel any attempts to store
1323 the processed statement associated with this writer.
1324 */
1325 query->writer()->first_query_block= NULL;
1326 query->writer(0);
1327 refused++;
1328 }
1329 query->unlock_n_destroy();
1330 block= block->next;
1331 } while (block != queries_blocks);
1332 queries_blocks= NULL; // avoid second destroying by free_cache
1333 }
1334 free_cache();
1335
1336 query_cache_size= query_cache_size_arg;
1337 new_query_cache_size= init_cache();
1338
1339 /*
1340 m_cache_status is internal query cache switch so switching it on/off
1341 will not be reflected on global_system_variables.query_cache_type
1342 */
1343 if (new_query_cache_size && global_system_variables.query_cache_type != 0)
1344 {
1345 DBUG_EXECUTE("check_querycache",check_integrity(1););
1346 m_cache_status= OK; // size > 0 => enable cache
1347 }
1348 else
1349 m_cache_status= DISABLED; // size 0 means the cache disabled
1350
1351 unlock();
1352 DBUG_RETURN(new_query_cache_size);
1353}
1354
1355
1356size_t Query_cache::set_min_res_unit(size_t size)
1357{
1358 DBUG_ASSERT(size % 8 == 0);
1359 if (size < min_allocation_unit)
1360 size= ALIGN_SIZE(min_allocation_unit);
1361 return (min_result_data_size= size);
1362}
1363
1364
1365void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
1366{
1367 TABLE_COUNTER_TYPE local_tables;
1368 size_t tot_length;
1369 const char *query;
1370 size_t query_length;
1371 uint8 tables_type;
1372 DBUG_ENTER("Query_cache::store_query");
1373 /*
1374 Testing 'query_cache_size' without a lock here is safe: the thing
1375 we may loose is that the query won't be cached, but we save on
1376 mutex locking in the case when query cache is disabled or the
1377 query is uncachable.
1378
1379 See also a note on double-check locking usage above.
1380 */
1381 if (!thd->query_cache_is_applicable || query_cache_size == 0)
1382 {
1383 DBUG_PRINT("qcache", ("Query cache not ready"));
1384 DBUG_VOID_RETURN;
1385 }
1386 if (thd->lex->sql_command != SQLCOM_SELECT)
1387 {
1388 DBUG_PRINT("qcache", ("Ignoring not SELECT command"));
1389 DBUG_VOID_RETURN;
1390 }
1391
1392 /*
1393 Do not store queries while tracking transaction state.
1394 The tracker already flags queries that actually have
1395 transaction tracker items, but this will make behavior
1396 more straight forward.
1397 */
1398#ifndef EMBEDDED_LIBRARY
1399 if (thd->variables.session_track_transaction_info != TX_TRACK_NONE)
1400 {
1401 DBUG_PRINT("qcache", ("Do not work with transaction tracking"));
1402 DBUG_VOID_RETURN;
1403 }
1404#endif //EMBEDDED_LIBRARY
1405
1406
1407 /* The following assert fails if we haven't called send_result_to_client */
1408 DBUG_ASSERT(thd->base_query.is_alloced() ||
1409 thd->base_query.ptr() == thd->query());
1410
1411 tables_type= 0;
1412 if ((local_tables= is_cacheable(thd, thd->lex, tables_used,
1413 &tables_type)))
1414 {
1415 NET *net= &thd->net;
1416 Query_cache_query_flags flags;
1417 // fill all gaps between fields with 0 to get repeatable key
1418 bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
1419 flags.client_long_flag= MY_TEST(thd->client_capabilities & CLIENT_LONG_FLAG);
1420 flags.client_protocol_41= MY_TEST(thd->client_capabilities &
1421 CLIENT_PROTOCOL_41);
1422 flags.client_depr_eof= MY_TEST(thd->client_capabilities &
1423 CLIENT_DEPRECATE_EOF);
1424 /*
1425 Protocol influences result format, so statement results in the binary
1426 protocol (COM_EXECUTE) cannot be served to statements asking for results
1427 in the text protocol (COM_QUERY) and vice-versa.
1428 */
1429 flags.protocol_type= (unsigned int) thd->protocol->type();
1430 /* PROTOCOL_LOCAL results are not cached. */
1431 DBUG_ASSERT(flags.protocol_type != (unsigned int) Protocol::PROTOCOL_LOCAL);
1432 flags.more_results_exists= MY_TEST(thd->server_status &
1433 SERVER_MORE_RESULTS_EXISTS);
1434 flags.in_trans= thd->in_active_multi_stmt_transaction();
1435 flags.autocommit= MY_TEST(thd->server_status & SERVER_STATUS_AUTOCOMMIT);
1436 flags.pkt_nr= net->pkt_nr;
1437 flags.character_set_client_num=
1438 thd->variables.character_set_client->number;
1439 flags.character_set_results_num=
1440 (thd->variables.character_set_results ?
1441 thd->variables.character_set_results->number :
1442 UINT_MAX);
1443 flags.collation_connection_num=
1444 thd->variables.collation_connection->number;
1445 flags.limit= thd->variables.select_limit;
1446 flags.time_zone= thd->variables.time_zone;
1447 flags.sql_mode= thd->variables.sql_mode;
1448 flags.max_sort_length= thd->variables.max_sort_length;
1449 flags.lc_time_names= thd->variables.lc_time_names;
1450 flags.group_concat_max_len= thd->variables.group_concat_max_len;
1451 flags.div_precision_increment= thd->variables.div_precincrement;
1452 flags.default_week_format= thd->variables.default_week_format;
1453 DBUG_PRINT("qcache", ("\
1454long %d, 4.1: %d, eof: %d, bin_proto: %d, more results %d, pkt_nr: %d, \
1455CS client: %u, CS result: %u, CS conn: %u, limit: %llu, TZ: %p, \
1456sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %zu, \
1457def_week_frmt: %zu, in_trans: %d, autocommit: %d",
1458 (int)flags.client_long_flag,
1459 (int)flags.client_protocol_41,
1460 (int)flags.client_depr_eof,
1461 (int)flags.protocol_type,
1462 (int)flags.more_results_exists,
1463 flags.pkt_nr,
1464 flags.character_set_client_num,
1465 flags.character_set_results_num,
1466 flags.collation_connection_num,
1467 (ulonglong)flags.limit,
1468 flags.time_zone,
1469 flags.sql_mode,
1470 flags.max_sort_length,
1471 flags.group_concat_max_len,
1472 flags.div_precision_increment,
1473 flags.default_week_format,
1474 (int)flags.in_trans,
1475 (int)flags.autocommit));
1476
1477 /*
1478 A table- or a full flush operation can potentially take a long time to
1479 finish. We choose not to wait for them and skip caching statements
1480 instead.
1481
1482 In case the wait time can't be determined there is an upper limit which
1483 causes try_lock() to abort with a time out.
1484
1485 The 'TIMEOUT' parameter indicate that the lock is allowed to timeout
1486
1487 */
1488 if (try_lock(thd, Query_cache::TIMEOUT))
1489 DBUG_VOID_RETURN;
1490 if (query_cache_size == 0)
1491 {
1492 unlock();
1493 DBUG_VOID_RETURN;
1494 }
1495 DUMP(this);
1496
1497 if (ask_handler_allowance(thd, tables_used))
1498 {
1499 refused++;
1500 unlock();
1501 DBUG_VOID_RETURN;
1502 }
1503
1504 query= thd->base_query.ptr();
1505 query_length= thd->base_query.length();
1506
1507 /* Key is query + database + flag */
1508 if (thd->db.length)
1509 {
1510 memcpy((char*) (query + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE),
1511 thd->db.str, thd->db.length);
1512 DBUG_PRINT("qcache", ("database: %s length: %u",
1513 thd->db.str, (unsigned) thd->db.length));
1514 }
1515 else
1516 {
1517 DBUG_PRINT("qcache", ("No active database"));
1518 }
1519 tot_length= (query_length + thd->db.length + 1 +
1520 QUERY_CACHE_DB_LENGTH_SIZE + QUERY_CACHE_FLAGS_SIZE);
1521 /*
1522 We should only copy structure (don't use it location directly)
1523 because of alignment issue
1524 */
1525 memcpy((void*) (query + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
1526 &flags, QUERY_CACHE_FLAGS_SIZE);
1527
1528 /* Check if another thread is processing the same query? */
1529 Query_cache_block *competitor = (Query_cache_block *)
1530 my_hash_search(&queries, (uchar*) query, tot_length);
1531 DBUG_PRINT("qcache", ("competitor %p", competitor));
1532 if (competitor == 0)
1533 {
1534 /* Query is not in cache and no one is working with it; Store it */
1535 Query_cache_block *query_block;
1536 query_block= write_block_data(tot_length, (uchar*) query,
1537 ALIGN_SIZE(sizeof(Query_cache_query)),
1538 Query_cache_block::QUERY, local_tables);
1539 if (query_block != 0)
1540 {
1541 DBUG_PRINT("qcache", ("query block %p allocated, %zu",
1542 query_block, query_block->used));
1543
1544 Query_cache_query *header = query_block->query();
1545 header->init_n_lock();
1546 if (my_hash_insert(&queries, (uchar*) query_block))
1547 {
1548 refused++;
1549 DBUG_PRINT("qcache", ("insertion in query hash"));
1550 header->unlock_n_destroy();
1551 free_memory_block(query_block);
1552 unlock();
1553 goto end;
1554 }
1555 if (!register_all_tables(thd, query_block, tables_used, local_tables))
1556 {
1557 refused++;
1558 DBUG_PRINT("warning", ("tables list including failed"));
1559 my_hash_delete(&queries, (uchar *) query_block);
1560 header->unlock_n_destroy();
1561 free_memory_block(query_block);
1562 unlock();
1563 goto end;
1564 }
1565 double_linked_list_simple_include(query_block, &queries_blocks);
1566 inserts++;
1567 queries_in_cache++;
1568 thd->query_cache_tls.first_query_block= query_block;
1569 header->writer(&thd->query_cache_tls);
1570 header->tables_type(tables_type);
1571
1572 unlock();
1573
1574 DEBUG_SYNC(thd, "wait_in_query_cache_store_query");
1575
1576 // init_n_lock make query block locked
1577 BLOCK_UNLOCK_WR(query_block);
1578 }
1579 else
1580 {
1581 // We have not enough memory to store query => do nothing
1582 refused++;
1583 unlock();
1584 DBUG_PRINT("warning", ("Can't allocate query"));
1585 }
1586 }
1587 else
1588 {
1589 // Another thread is processing the same query => do nothing
1590 refused++;
1591 unlock();
1592 DBUG_PRINT("qcache", ("Another thread process same query"));
1593 }
1594 }
1595 else
1596 statistic_increment(refused, &structure_guard_mutex);
1597
1598end:
1599 DBUG_VOID_RETURN;
1600}
1601
1602
1603#ifndef EMBEDDED_LIBRARY
1604/**
1605 Send a single memory block from the query cache.
1606
1607 Respects the client/server protocol limits for the
1608 size of the network packet, and splits a large block
1609 in pieces to ensure that individual piece doesn't exceed
1610 the maximal allowed size of the network packet (16M).
1611
1612 @param[in] net NET handler
1613 @param[in] packet packet to send
1614 @param[in] len packet length
1615
1616 @return Operation status
1617 @retval FALSE On success
1618 @retval TRUE On error
1619*/
1620static bool
1621send_data_in_chunks(NET *net, const uchar *packet, size_t len)
1622{
1623 /*
1624 On the client we may require more memory than max_allowed_packet
1625 to keep, both, the truncated last logical packet, and the
1626 compressed next packet. This never (or in practice never)
1627 happens without compression, since without compression it's very
1628 unlikely that a) a truncated logical packet would remain on the
1629 client when it's time to read the next packet b) a subsequent
1630 logical packet that is being read would be so large that
1631 size-of-new-packet + size-of-old-packet-tail >
1632 max_allowed_packet. To remedy this issue, we send data in 1MB
1633 sized packets, that's below the current client default of 16MB
1634 for max_allowed_packet, but large enough to ensure there is no
1635 unnecessary overhead from too many syscalls per result set.
1636 */
1637 static const size_t MAX_CHUNK_LENGTH= 1024*1024;
1638
1639 while (len > MAX_CHUNK_LENGTH)
1640 {
1641 if (net_real_write(net, packet, MAX_CHUNK_LENGTH))
1642 return TRUE;
1643 packet+= MAX_CHUNK_LENGTH;
1644 len-= MAX_CHUNK_LENGTH;
1645 }
1646 if (len && net_real_write(net, packet, len))
1647 return TRUE;
1648
1649 return FALSE;
1650}
1651#endif
1652
1653
1654/**
1655 Build a normalized table name suitable for query cache engine callback
1656
1657 This consist of normalized directory '/' normalized_file_name
1658 followed by suffix.
1659 Suffix is needed for partitioned tables.
1660*/
1661
1662size_t build_normalized_name(char *buff, size_t bufflen,
1663 const char *db, size_t db_len,
1664 const char *table_name, size_t table_len,
1665 size_t suffix_len)
1666{
1667 uint errors;
1668 size_t length;
1669 char *pos= buff, *end= buff+bufflen;
1670 DBUG_ENTER("build_normalized_name");
1671
1672 (*pos++)= FN_LIBCHAR;
1673 length= strconvert(system_charset_info, db, db_len,
1674 &my_charset_filename, pos, bufflen - 3,
1675 &errors);
1676 pos+= length;
1677 (*pos++)= FN_LIBCHAR;
1678 length= strconvert(system_charset_info, table_name, table_len,
1679 &my_charset_filename, pos, (uint) (end - pos),
1680 &errors);
1681 pos+= length;
1682 if (pos + suffix_len < end)
1683 pos= strmake(pos, table_name + table_len, suffix_len);
1684
1685 DBUG_RETURN((size_t) (pos - buff));
1686}
1687
1688
1689/*
1690 Check if the query is in the cache. If it was cached, send it
1691 to the user.
1692
1693 @param thd Pointer to the thread handler
1694 @param org_sql A pointer to the sql statement *
1695 @param query_length Length of the statement in characters
1696
1697 @return status code
1698 @retval 0 Query was not cached.
1699 @retval 1 The query was cached and user was sent the result.
1700 @retval -1 The query was cached but we didn't have rights to use it.
1701
1702 In case of -1, no error is sent to the client.
1703
1704 *) The buffer must be allocated memory of size:
1705 tot_length= query_length + thd->db.length + 1 + QUERY_CACHE_FLAGS_SIZE;
1706*/
1707
1708int
1709Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
1710{
1711 ulonglong engine_data;
1712 Query_cache_query *query;
1713#ifndef EMBEDDED_LIBRARY
1714 Query_cache_block *first_result_block;
1715#endif
1716 Query_cache_block *result_block;
1717 Query_cache_block_table *block_table, *block_table_end;
1718 size_t tot_length;
1719 Query_cache_query_flags flags;
1720 const char *sql, *sql_end, *found_brace= 0;
1721 DBUG_ENTER("Query_cache::send_result_to_client");
1722
1723 /*
1724 Testing without a lock here is safe: the thing
1725 we may loose is that the query won't be served from cache, but we
1726 save on mutex locking in the case when query cache is disabled.
1727
1728 See also a note on double-check locking usage above.
1729 */
1730 if (is_disabled() || thd->locked_tables_mode ||
1731 thd->variables.query_cache_type == 0)
1732 goto err;
1733
1734 /*
1735 The following can only happen for prepared statements that was found
1736 during parsing or later that the query was not cacheable.
1737 */
1738 if (!thd->lex->safe_to_cache_query)
1739 {
1740 DBUG_PRINT("qcache", ("SELECT is non-cacheable"));
1741 goto err;
1742 }
1743
1744 /*
1745 Don't allow serving from Query_cache while tracking transaction
1746 state. This is a safeguard in case an otherwise matching query
1747 was added to the cache before tracking was turned on.
1748 */
1749#ifndef EMBEDDED_LIBRARY
1750 if (thd->variables.session_track_transaction_info != TX_TRACK_NONE)
1751 {
1752 DBUG_PRINT("qcache", ("Do not work with transaction tracking"));
1753 goto err;
1754 }
1755#endif //EMBEDDED_LIBRARY
1756
1757
1758 thd->query_cache_is_applicable= 1;
1759 sql= org_sql; sql_end= sql + query_length;
1760
1761 /*
1762 Skip all comments at start of query. The following tests is false for
1763 all normal queries.
1764 */
1765 if (!my_isalpha(system_charset_info, *sql))
1766 {
1767 while (sql < sql_end)
1768 {
1769 char current= *sql;
1770 switch (current) {
1771 case '/':
1772 if (sql[1] != '*')
1773 break;
1774 sql+= 2; // Skip '/*'
1775 if (*sql == '!')
1776 {
1777 /*
1778 Found / *!number comment; Skip number to see if sql
1779 starts with 'select'
1780 */
1781 sql++;
1782 while (my_isdigit(system_charset_info, *sql))
1783 sql++;
1784 }
1785 else
1786 {
1787 while (sql++ < sql_end)
1788 {
1789 if (sql[-1] == '*' && *sql == '/')
1790 {
1791 sql++;
1792 break;
1793 }
1794 }
1795 }
1796 continue;
1797 case '-':
1798 if (sql[1] != '-' || !is_white_space(sql[2])) // Not a comment
1799 break;
1800 sql++; // Skip first '-'
1801 /* Fall through */
1802 case '#':
1803 while (++sql < sql_end)
1804 {
1805 if (*sql == '\n')
1806 {
1807 sql++; // Skip '\n'
1808 break;
1809 }
1810 }
1811 /* Continue with analyzing current symbol */
1812 continue;
1813 case '\r':
1814 case '\n':
1815 case '\t':
1816 case ' ':
1817 sql++;
1818 continue;
1819 case '(': // To handle (select a from t1) union (select a from t1);
1820 if (!found_brace)
1821 {
1822 found_brace= sql;
1823 sql++;
1824 continue;
1825 }
1826 /* fall through */
1827 default:
1828 break;
1829 }
1830 /* We only come here when we found the first word of the sql */
1831 break;
1832 }
1833 }
1834 if ((my_toupper(system_charset_info, sql[0]) != 'S' ||
1835 my_toupper(system_charset_info, sql[1]) != 'E' ||
1836 my_toupper(system_charset_info, sql[2]) != 'L') &&
1837 (my_toupper(system_charset_info, sql[0]) != 'W' ||
1838 my_toupper(system_charset_info, sql[1]) != 'I' ||
1839 my_toupper(system_charset_info, sql[2]) != 'T'))
1840 {
1841 DBUG_PRINT("qcache", ("The statement is not a SELECT; Not cached"));
1842 goto err;
1843 }
1844
1845 if ((sql_end - sql) > 20 && has_no_cache_directive(sql+6))
1846 {
1847 /*
1848 We do not increase 'refused' statistics here since it will be done
1849 later when the query is parsed.
1850 */
1851 DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive"));
1852 goto err;
1853 }
1854 {
1855 /*
1856 We have allocated buffer space (in alloc_query) to hold the
1857 SQL statement(s) + the current database name + a flags struct.
1858 If the database name has changed during execution, which might
1859 happen if there are multiple statements, we need to make
1860 sure the new current database has a name with the same length
1861 as the previous one.
1862 */
1863 size_t db_len= uint2korr(sql_end+1);
1864 if (thd->db.length != db_len)
1865 {
1866 /*
1867 We should probably reallocate the buffer in this case,
1868 but for now we just leave it uncached
1869 */
1870
1871 DBUG_PRINT("qcache",
1872 ("Current database has changed since start of query"));
1873 goto err;
1874 }
1875 }
1876 /*
1877 Try to obtain an exclusive lock on the query cache. If the cache is
1878 disabled or if a full cache flush is in progress, the attempt to
1879 get the lock is aborted.
1880
1881 The TIMEOUT parameter indicate that the lock is allowed to timeout.
1882 */
1883 if (try_lock(thd, Query_cache::TIMEOUT))
1884 goto err;
1885
1886 if (query_cache_size == 0)
1887 {
1888 thd->query_cache_is_applicable= 0; // Query can't be cached
1889 goto err_unlock;
1890 }
1891
1892 Query_cache_block *query_block;
1893 if (thd->variables.query_cache_strip_comments)
1894 {
1895 if (found_brace)
1896 sql= found_brace;
1897 make_base_query(&thd->base_query, sql, (size_t) (sql_end - sql),
1898 thd->db.length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
1899 QUERY_CACHE_FLAGS_SIZE);
1900 sql= thd->base_query.ptr();
1901 query_length= thd->base_query.length();
1902 }
1903 else
1904 {
1905 sql= org_sql;
1906 thd->base_query.set(sql, query_length, system_charset_info);
1907 }
1908
1909 tot_length= (query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
1910 thd->db.length + QUERY_CACHE_FLAGS_SIZE);
1911
1912 if (thd->db.length)
1913 {
1914 memcpy((uchar*) sql + query_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE,
1915 thd->db.str, thd->db.length);
1916 DBUG_PRINT("qcache", ("database: '%s' length: %u",
1917 thd->db.str, (uint) thd->db.length));
1918 }
1919 else
1920 {
1921 DBUG_PRINT("qcache", ("No active database"));
1922 }
1923
1924 THD_STAGE_INFO(thd, stage_checking_query_cache_for_query);
1925
1926 // fill all gaps between fields with 0 to get repeatable key
1927 bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
1928 flags.client_long_flag= MY_TEST(thd->client_capabilities & CLIENT_LONG_FLAG);
1929 flags.client_protocol_41= MY_TEST(thd->client_capabilities &
1930 CLIENT_PROTOCOL_41);
1931 flags.client_depr_eof= MY_TEST(thd->client_capabilities &
1932 CLIENT_DEPRECATE_EOF);
1933 flags.protocol_type= (unsigned int) thd->protocol->type();
1934 flags.more_results_exists= MY_TEST(thd->server_status &
1935 SERVER_MORE_RESULTS_EXISTS);
1936 flags.in_trans= thd->in_active_multi_stmt_transaction();
1937 flags.autocommit= MY_TEST(thd->server_status & SERVER_STATUS_AUTOCOMMIT);
1938 flags.pkt_nr= thd->net.pkt_nr;
1939 flags.character_set_client_num= thd->variables.character_set_client->number;
1940 flags.character_set_results_num=
1941 (thd->variables.character_set_results ?
1942 thd->variables.character_set_results->number :
1943 UINT_MAX);
1944 flags.collation_connection_num= thd->variables.collation_connection->number;
1945 flags.limit= thd->variables.select_limit;
1946 flags.time_zone= thd->variables.time_zone;
1947 flags.sql_mode= thd->variables.sql_mode;
1948 flags.max_sort_length= thd->variables.max_sort_length;
1949 flags.group_concat_max_len= thd->variables.group_concat_max_len;
1950 flags.div_precision_increment= thd->variables.div_precincrement;
1951 flags.default_week_format= thd->variables.default_week_format;
1952 flags.lc_time_names= thd->variables.lc_time_names;
1953 DBUG_PRINT("qcache", ("\
1954long %d, 4.1: %d, eof: %d, bin_proto: %d, more results %d, pkt_nr: %d, \
1955CS client: %u, CS result: %u, CS conn: %u, limit: %llu, TZ: %p, \
1956sql mode: 0x%llx, sort len: %llu, conncat len: %llu, div_precision: %zu, \
1957def_week_frmt: %zu, in_trans: %d, autocommit: %d",
1958 (int)flags.client_long_flag,
1959 (int)flags.client_protocol_41,
1960 (int)flags.client_depr_eof,
1961 (int)flags.protocol_type,
1962 (int)flags.more_results_exists,
1963 flags.pkt_nr,
1964 flags.character_set_client_num,
1965 flags.character_set_results_num,
1966 flags.collation_connection_num,
1967 (ulonglong) flags.limit,
1968 flags.time_zone,
1969 flags.sql_mode,
1970 flags.max_sort_length,
1971 flags.group_concat_max_len,
1972 flags.div_precision_increment,
1973 flags.default_week_format,
1974 (int)flags.in_trans,
1975 (int)flags.autocommit));
1976 memcpy((uchar *)(sql + (tot_length - QUERY_CACHE_FLAGS_SIZE)),
1977 (uchar*) &flags, QUERY_CACHE_FLAGS_SIZE);
1978
1979#ifdef WITH_WSREP
1980 bool once_more;
1981 once_more= true;
1982lookup:
1983#endif /* WITH_WSREP */
1984
1985 query_block = (Query_cache_block *) my_hash_search(&queries, (uchar*) sql,
1986 tot_length);
1987 /* Quick abort on unlocked data */
1988 if (query_block == 0 ||
1989 query_block->query()->result() == 0 ||
1990 query_block->query()->result()->type != Query_cache_block::RESULT)
1991 {
1992 DBUG_PRINT("qcache", ("No query in query hash or no results"));
1993 goto err_unlock;
1994 }
1995 DBUG_PRINT("qcache", ("Query in query hash %p",query_block));
1996
1997#ifdef WITH_WSREP
1998 if (once_more && WSREP_CLIENT(thd) && wsrep_must_sync_wait(thd))
1999 {
2000 unlock();
2001 if (wsrep_sync_wait(thd))
2002 goto err;
2003 if (try_lock(thd, Query_cache::TIMEOUT))
2004 goto err;
2005 once_more= false;
2006 goto lookup;
2007 }
2008#endif /* WITH_WSREP */
2009
2010 /* Now lock and test that nothing changed while blocks was unlocked */
2011 BLOCK_LOCK_RD(query_block);
2012
2013 query = query_block->query();
2014 result_block= query->result();
2015#ifndef EMBEDDED_LIBRARY
2016 first_result_block= result_block;
2017#endif
2018
2019 if (result_block == 0 || result_block->type != Query_cache_block::RESULT)
2020 {
2021 /* The query is probably yet processed */
2022 DBUG_PRINT("qcache", ("query found, but no data or data incomplete"));
2023 BLOCK_UNLOCK_RD(query_block);
2024 goto err_unlock;
2025 }
2026 DBUG_PRINT("qcache", ("Query have result %p", query));
2027
2028 if (thd->in_multi_stmt_transaction_mode() &&
2029 (query->tables_type() & HA_CACHE_TBL_TRANSACT))
2030 {
2031 DBUG_PRINT("qcache",
2032 ("we are in transaction and have transaction tables in query"));
2033 BLOCK_UNLOCK_RD(query_block);
2034 goto err_unlock;
2035 }
2036
2037 // Check access;
2038 THD_STAGE_INFO(thd, stage_checking_privileges_on_cached_query);
2039 block_table= query_block->table(0);
2040 block_table_end= block_table+query_block->n_tables;
2041 for (; block_table != block_table_end; block_table++)
2042 {
2043 TABLE_LIST table_list;
2044 TMP_TABLE_SHARE *tmptable;
2045 Query_cache_table *table = block_table->parent;
2046
2047 /*
2048 Check that we do not have temporary tables with same names as that of
2049 base tables from this query. If we have such tables, we will not send
2050 data from query cache, because temporary tables hide real tables by which
2051 query in query cache was made.
2052 */
2053 if ((tmptable=
2054 thd->find_tmp_table_share_w_base_key((char *) table->data(),
2055 table->key_length())))
2056 {
2057 DBUG_PRINT("qcache",
2058 ("Temporary table detected: '%s.%s'",
2059 tmptable->db.str, tmptable->table_name.str));
2060 unlock();
2061 /*
2062 We should not store result of this query because it contain
2063 temporary tables => assign following variable to make check
2064 faster.
2065 */
2066 thd->query_cache_is_applicable= 0; // Query can't be cached
2067 thd->lex->safe_to_cache_query= 0; // For prepared statements
2068 BLOCK_UNLOCK_RD(query_block);
2069 DBUG_RETURN(-1);
2070 }
2071
2072 bzero((char*) &table_list,sizeof(table_list));
2073 table_list.db.str= table->db();
2074 table_list.db.length= strlen(table_list.db.str);
2075 table_list.alias.str= table_list.table_name.str= table->table();
2076 table_list.alias.length= table_list.table_name.length= strlen(table->table());
2077
2078#ifndef NO_EMBEDDED_ACCESS_CHECKS
2079 if (check_table_access(thd,SELECT_ACL,&table_list, FALSE, 1,TRUE))
2080 {
2081 DBUG_PRINT("qcache",
2082 ("probably no SELECT access to %s.%s => return to normal processing",
2083 table_list.db.str, table_list.alias.str));
2084 unlock();
2085 thd->query_cache_is_applicable= 0; // Query can't be cached
2086 thd->lex->safe_to_cache_query= 0; // For prepared statements
2087 BLOCK_UNLOCK_RD(query_block);
2088 DBUG_RETURN(-1); // Privilege error
2089 }
2090 if (table_list.grant.want_privilege)
2091 {
2092 DBUG_PRINT("qcache", ("Need to check column privileges for %s.%s",
2093 table_list.db.str, table_list.alias.str));
2094 BLOCK_UNLOCK_RD(query_block);
2095 thd->query_cache_is_applicable= 0; // Query can't be cached
2096 thd->lex->safe_to_cache_query= 0; // For prepared statements
2097 goto err_unlock; // Parse query
2098 }
2099#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
2100 engine_data= table->engine_data();
2101 if (table->callback())
2102 {
2103 char qcache_se_key_name[FN_REFLEN + 10];
2104 size_t qcache_se_key_len, db_length= strlen(table->db());
2105 engine_data= table->engine_data();
2106
2107 qcache_se_key_len= build_normalized_name(qcache_se_key_name,
2108 sizeof(qcache_se_key_name),
2109 table->db(),
2110 db_length,
2111 table->table(),
2112 table->key_length() -
2113 db_length - 2 -
2114 table->suffix_length(),
2115 table->suffix_length());
2116
2117 if (!(*table->callback())(thd, qcache_se_key_name,
2118 (uint)qcache_se_key_len, &engine_data))
2119 {
2120 DBUG_PRINT("qcache", ("Handler does not allow caching for %.*s",
2121 (int)qcache_se_key_len, qcache_se_key_name));
2122 BLOCK_UNLOCK_RD(query_block);
2123 if (engine_data != table->engine_data())
2124 {
2125 DBUG_PRINT("qcache",
2126 ("Handler require invalidation queries of %.*s %llu-%llu",
2127 (int)qcache_se_key_len, qcache_se_key_name,
2128 engine_data, table->engine_data()));
2129 invalidate_table_internal(thd,
2130 (uchar *) table->db(),
2131 table->key_length());
2132 }
2133 else
2134 {
2135 /*
2136 As this can change from call to call, don't reset set
2137 thd->lex->safe_to_cache_query
2138 */
2139 thd->query_cache_is_applicable= 0; // Query can't be cached
2140 }
2141 /*
2142 End the statement transaction potentially started by engine.
2143 Currently our engines do not request rollback from callbacks.
2144 If this is going to change code needs to be reworked.
2145 */
2146 DBUG_ASSERT(! thd->transaction_rollback_request);
2147 trans_rollback_stmt(thd);
2148 goto err_unlock; // Parse query
2149 }
2150 }
2151 else
2152 DBUG_PRINT("qcache", ("handler allow caching %s,%s",
2153 table_list.db.str, table_list.alias.str));
2154 }
2155 move_to_query_list_end(query_block);
2156 hits++;
2157 query->increment_hits();
2158 unlock();
2159
2160 /*
2161 Send cached result to client
2162 */
2163#ifndef EMBEDDED_LIBRARY
2164 THD_STAGE_INFO(thd, stage_sending_cached_result_to_client);
2165 do
2166 {
2167 DBUG_PRINT("qcache", ("Results (len: %zu used: %zu headers: %u)",
2168 result_block->length, result_block->used,
2169 (uint) (result_block->headers_len()+
2170 ALIGN_SIZE(sizeof(Query_cache_result)))));
2171
2172 Query_cache_result *result = result_block->result();
2173 if (send_data_in_chunks(&thd->net, result->data(),
2174 result_block->used -
2175 result_block->headers_len() -
2176 ALIGN_SIZE(sizeof(Query_cache_result))))
2177 break; // Client aborted
2178 result_block = result_block->next;
2179 thd->net.pkt_nr= query->last_pkt_nr; // Keep packet number updated
2180 } while (result_block != first_result_block);
2181#else
2182 {
2183 Querycache_stream qs(result_block, result_block->headers_len() +
2184 ALIGN_SIZE(sizeof(Query_cache_result)));
2185 emb_load_querycache_result(thd, &qs);
2186 }
2187#endif /*!EMBEDDED_LIBRARY*/
2188
2189 thd->set_sent_row_count(thd->limit_found_rows = query->found_rows());
2190 thd->status_var.last_query_cost= 0.0;
2191 thd->query_plan_flags= (thd->query_plan_flags & ~QPLAN_QC_NO) | QPLAN_QC;
2192 if (!thd->get_sent_row_count())
2193 status_var_increment(thd->status_var.empty_queries);
2194 else
2195 status_var_add(thd->status_var.rows_sent, thd->get_sent_row_count());
2196
2197 /*
2198 End the statement transaction potentially started by an
2199 engine callback. We ignore the return value for now,
2200 since as long as EOF packet is part of the query cache
2201 response, we can't handle it anyway.
2202 */
2203 (void) trans_commit_stmt(thd);
2204 thd->get_stmt_da()->disable_status();
2205
2206 BLOCK_UNLOCK_RD(query_block);
2207 MYSQL_QUERY_CACHE_HIT(thd->query(), thd->limit_found_rows);
2208 DBUG_RETURN(1); // Result sent to client
2209
2210err_unlock:
2211 unlock();
2212 MYSQL_QUERY_CACHE_MISS(thd->query());
2213 /*
2214 query_plan_flags doesn't have to be changed here as it contains
2215 QPLAN_QC_NO by default
2216 */
2217 DBUG_RETURN(0); // Query was not cached
2218
2219err:
2220 thd->query_cache_is_applicable= 0; // Query can't be cached
2221 DBUG_RETURN(0); // Query was not cached
2222}
2223
2224
2225/*
2226 Remove all cached queries that uses any of the tables in the list
2227*/
2228
2229void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
2230 my_bool using_transactions)
2231{
2232 DBUG_ENTER("Query_cache::invalidate (table list)");
2233 if (is_disabled())
2234 DBUG_VOID_RETURN;
2235
2236 using_transactions= using_transactions && thd->in_multi_stmt_transaction_mode();
2237 for (; tables_used; tables_used= tables_used->next_local)
2238 {
2239 DBUG_ASSERT(!using_transactions || tables_used->table!=0);
2240 if (tables_used->derived)
2241 continue;
2242 if (using_transactions &&
2243 (tables_used->table->file->table_cache_type() ==
2244 HA_CACHE_TBL_TRANSACT))
2245 /*
2246 tables_used->table can't be 0 in transaction.
2247 Only 'drop' invalidate not opened table, but 'drop'
2248 force transaction finish.
2249 */
2250 thd->add_changed_table(tables_used->table);
2251 else
2252 invalidate_table(thd, tables_used);
2253 }
2254
2255 DEBUG_SYNC(thd, "wait_after_query_cache_invalidate");
2256
2257 DBUG_VOID_RETURN;
2258}
2259
2260void Query_cache::invalidate(THD *thd, CHANGED_TABLE_LIST *tables_used)
2261{
2262 DBUG_ENTER("Query_cache::invalidate (changed table list)");
2263 if (is_disabled())
2264 DBUG_VOID_RETURN;
2265
2266 for (; tables_used; tables_used= tables_used->next)
2267 {
2268 THD_STAGE_INFO(thd, stage_invalidating_query_cache_entries_table_list);
2269 invalidate_table(thd, (uchar*) tables_used->key, tables_used->key_length);
2270 DBUG_PRINT("qcache", ("db: %s table: %s", tables_used->key,
2271 tables_used->key+
2272 strlen(tables_used->key)+1));
2273 }
2274 DBUG_VOID_RETURN;
2275}
2276
2277
2278/*
2279 Invalidate locked for write
2280
2281 SYNOPSIS
2282 Query_cache::invalidate_locked_for_write()
2283 tables_used - table list
2284
2285 NOTE
2286 can be used only for opened tables
2287*/
2288void Query_cache::invalidate_locked_for_write(THD *thd,
2289 TABLE_LIST *tables_used)
2290{
2291 DBUG_ENTER("Query_cache::invalidate_locked_for_write");
2292 if (is_disabled())
2293 DBUG_VOID_RETURN;
2294
2295 for (; tables_used; tables_used= tables_used->next_local)
2296 {
2297 THD_STAGE_INFO(thd, stage_invalidating_query_cache_entries_table);
2298 if (tables_used->lock_type >= TL_WRITE_ALLOW_WRITE &&
2299 tables_used->table)
2300 {
2301 invalidate_table(thd, tables_used->table);
2302 }
2303 }
2304 DBUG_VOID_RETURN;
2305}
2306
2307/*
2308 Remove all cached queries that uses the given table
2309*/
2310
2311void Query_cache::invalidate(THD *thd, TABLE *table,
2312 my_bool using_transactions)
2313{
2314 DBUG_ENTER("Query_cache::invalidate (table)");
2315 if (is_disabled())
2316 DBUG_VOID_RETURN;
2317
2318 using_transactions= using_transactions && thd->in_multi_stmt_transaction_mode();
2319 if (using_transactions &&
2320 (table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT))
2321 thd->add_changed_table(table);
2322 else
2323 invalidate_table(thd, table);
2324
2325
2326 DBUG_VOID_RETURN;
2327}
2328
2329void Query_cache::invalidate(THD *thd, const char *key, size_t key_length,
2330 my_bool using_transactions)
2331{
2332 DBUG_ENTER("Query_cache::invalidate (key)");
2333 if (is_disabled())
2334 DBUG_VOID_RETURN;
2335
2336 using_transactions= using_transactions && thd->in_multi_stmt_transaction_mode();
2337 if (using_transactions) // used for innodb => has_transactions() is TRUE
2338 thd->add_changed_table(key, key_length);
2339 else
2340 invalidate_table(thd, (uchar*)key, key_length);
2341
2342 DBUG_VOID_RETURN;
2343}
2344
2345
2346/**
2347 Remove all cached queries that uses the given database.
2348*/
2349
2350void Query_cache::invalidate(THD *thd, const char *db)
2351{
2352 DBUG_ENTER("Query_cache::invalidate (db)");
2353 if (is_disabled())
2354 DBUG_VOID_RETURN;
2355
2356 DBUG_SLOW_ASSERT(ok_for_lower_case_names(db));
2357
2358 bool restart= FALSE;
2359 /*
2360 Lock the query cache and queue all invalidation attempts to avoid
2361 the risk of a race between invalidation, cache inserts and flushes.
2362 */
2363 lock(thd);
2364
2365 if (query_cache_size > 0)
2366 {
2367 if (tables_blocks)
2368 {
2369 Query_cache_block *table_block = tables_blocks;
2370 do {
2371 restart= FALSE;
2372 do
2373 {
2374 Query_cache_block *next= table_block->next;
2375 Query_cache_table *table = table_block->table();
2376 if (strcmp(table->db(),db) == 0)
2377 {
2378 Query_cache_block_table *list_root= table_block->table(0);
2379 invalidate_query_block_list(thd,list_root);
2380 }
2381
2382 table_block= next;
2383
2384 /*
2385 If our root node to used tables became null then the last element
2386 in the table list was removed when a query was invalidated;
2387 Terminate the search.
2388 */
2389 if (tables_blocks == 0)
2390 {
2391 table_block= tables_blocks;
2392 }
2393 /*
2394 If the iterated list has changed underlying structure;
2395 we need to restart the search.
2396 */
2397 else if (table_block->type == Query_cache_block::FREE)
2398 {
2399 restart= TRUE;
2400 table_block= tables_blocks;
2401 }
2402 /*
2403 The used tables are linked in a circular list;
2404 loop until we return to the beginning.
2405 */
2406 } while (table_block != tables_blocks);
2407 /*
2408 Invalidating a table will also mean that all cached queries using
2409 this table also will be invalidated. This will in turn change the
2410 list of tables associated with these queries and the linked list of
2411 used table will be changed. Because of this we might need to restart
2412 the search when a table has been invalidated.
2413 */
2414 } while (restart);
2415 } // end if( tables_blocks )
2416 }
2417 unlock();
2418
2419 DBUG_VOID_RETURN;
2420}
2421
2422
2423void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
2424{
2425 DBUG_ENTER("Query_cache::invalidate_by_MyISAM_filename");
2426
2427 if (is_disabled())
2428 DBUG_VOID_RETURN;
2429
2430 /* Calculate the key outside the lock to make the lock shorter */
2431 char key[MAX_DBKEY_LENGTH];
2432 uint32 db_length;
2433 uint key_length= filename_2_table_key(key, filename, &db_length);
2434 THD *thd= current_thd;
2435 invalidate_table(thd,(uchar *)key, key_length);
2436 DBUG_VOID_RETURN;
2437}
2438
2439 /* Remove all queries from cache */
2440
2441void Query_cache::flush()
2442{
2443 DBUG_ENTER("Query_cache::flush");
2444 if (is_disabled())
2445 DBUG_VOID_RETURN;
2446
2447 QC_DEBUG_SYNC("wait_in_query_cache_flush1");
2448
2449 lock_and_suspend();
2450 if (query_cache_size > 0)
2451 {
2452 DUMP(this);
2453 flush_cache();
2454 DUMP(this);
2455 }
2456
2457 DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
2458 unlock();
2459 DBUG_VOID_RETURN;
2460}
2461
2462
2463/**
2464 Rearrange the memory blocks and join result in cache in 1 block (if
2465 result length > join_limit)
2466
2467 @param[in] join_limit If the minimum length of a result block to be joined.
2468 @param[in] iteration_limit The maximum number of packing and joining
2469 sequences.
2470
2471*/
2472
2473void Query_cache::pack(THD *thd, size_t join_limit, uint iteration_limit)
2474{
2475 DBUG_ENTER("Query_cache::pack");
2476
2477 if (is_disabled())
2478 DBUG_VOID_RETURN;
2479
2480 /*
2481 If the entire qc is being invalidated we can bail out early
2482 instead of waiting for the lock.
2483 */
2484 if (try_lock(thd, Query_cache::WAIT))
2485 DBUG_VOID_RETURN;
2486
2487 if (query_cache_size == 0)
2488 {
2489 unlock();
2490 DBUG_VOID_RETURN;
2491 }
2492
2493 uint i = 0;
2494 do
2495 {
2496 pack_cache();
2497 } while ((++i < iteration_limit) && join_results(join_limit));
2498
2499 unlock();
2500 DBUG_VOID_RETURN;
2501}
2502
2503
2504void Query_cache::destroy()
2505{
2506 DBUG_ENTER("Query_cache::destroy");
2507 if (!initialized)
2508 {
2509 DBUG_PRINT("qcache", ("Query Cache not initialized"));
2510 }
2511 else
2512 {
2513 /* Underlying code expects the lock. */
2514 lock_and_suspend();
2515 free_cache();
2516 unlock();
2517
2518 mysql_cond_destroy(&COND_cache_status_changed);
2519 mysql_mutex_destroy(&structure_guard_mutex);
2520 initialized = 0;
2521 DBUG_ASSERT(m_requests_in_progress == 0);
2522 }
2523 DBUG_VOID_RETURN;
2524}
2525
2526
2527void Query_cache::disable_query_cache(THD *thd)
2528{
2529 m_cache_status= DISABLE_REQUEST;
2530 /*
2531 If there is no requests in progress try to free buffer.
2532 try_lock(TRY) will exit immediately if there is lock.
2533 unlock() should free block.
2534 */
2535 if (m_requests_in_progress == 0 && !try_lock(thd, TRY))
2536 unlock();
2537}
2538
2539
2540/*****************************************************************************
2541 init/destroy
2542*****************************************************************************/
2543
2544void Query_cache::init()
2545{
2546 DBUG_ENTER("Query_cache::init");
2547 mysql_mutex_init(key_structure_guard_mutex,
2548 &structure_guard_mutex, MY_MUTEX_INIT_FAST);
2549 mysql_cond_init(key_COND_cache_status_changed,
2550 &COND_cache_status_changed, NULL);
2551 m_cache_lock_status= Query_cache::UNLOCKED;
2552 m_cache_status= Query_cache::OK;
2553 m_requests_in_progress= 0;
2554 initialized = 1;
2555 /*
2556 Using state_map from latin1 should be fine in all cases:
2557 1. We do not support UCS2, UTF16, UTF32 as a client character set.
2558 2. The other character sets are compatible on the lower ASCII-range
2559 0x00-0x20, and have the following characters marked as spaces:
2560
2561 0x09 TAB
2562 0x0A LINE FEED
2563 0x0B VERTICAL TAB
2564 0x0C FORM FEED
2565 0x0D CARRIAGE RETUR
2566 0x20 SPACE
2567
2568 Additionally, only some of the ASCII-compatible character sets
2569 (including latin1) can have 0xA0 mapped to "NON-BREAK SPACE"
2570 and thus marked as space.
2571 That should not be a problem for those charsets that map 0xA0
2572 to something else: the parser will just return syntax error
2573 if this character appears straight in the query
2574 (i.e. not inside a string literal or comment).
2575 */
2576 query_state_map= my_charset_latin1.state_map;
2577 /*
2578 If we explicitly turn off query cache from the command line query
2579 cache will be disabled for the reminder of the server life
2580 time. This is because we want to avoid locking the QC specific
2581 mutex if query cache isn't going to be used.
2582 */
2583 if (global_system_variables.query_cache_type == 0)
2584 {
2585 m_cache_status= DISABLE_REQUEST;
2586 free_cache();
2587 m_cache_status= DISABLED;
2588 }
2589 DBUG_VOID_RETURN;
2590}
2591
2592
2593size_t Query_cache::init_cache()
2594{
2595 size_t mem_bin_count, num, step;
2596 size_t mem_bin_size, prev_size, inc;
2597 size_t max_mem_bin_size, approx_additional_data_size;
2598 int align;
2599
2600 DBUG_ENTER("Query_cache::init_cache");
2601
2602 approx_additional_data_size = (sizeof(Query_cache) +
2603 sizeof(uchar*)*(def_query_hash_size+
2604 def_table_hash_size));
2605 if (query_cache_size < approx_additional_data_size)
2606 goto err;
2607
2608 query_cache_size-= approx_additional_data_size;
2609 align= query_cache_size % ALIGN_SIZE(1);
2610 if (align)
2611 {
2612 query_cache_size-= align;
2613 approx_additional_data_size+= align;
2614 }
2615
2616 /*
2617 Count memory bins number.
2618 Check section 6. in start comment for the used algorithm.
2619 */
2620
2621 max_mem_bin_size = query_cache_size >> QUERY_CACHE_MEM_BIN_FIRST_STEP_PWR2;
2622 mem_bin_count = (uint) ((1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
2623 QUERY_CACHE_MEM_BIN_PARTS_MUL);
2624 mem_bin_num = 1;
2625 mem_bin_steps = 1;
2626 mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
2627 prev_size = 0;
2628 if (mem_bin_size <= min_allocation_unit)
2629 {
2630 DBUG_PRINT("qcache", ("too small query cache => query cache disabled"));
2631 // TODO here (and above) should be warning in 4.1
2632 goto err;
2633 }
2634 while (mem_bin_size > min_allocation_unit)
2635 {
2636 mem_bin_num += mem_bin_count;
2637 prev_size = mem_bin_size;
2638 mem_bin_size >>= QUERY_CACHE_MEM_BIN_STEP_PWR2;
2639 mem_bin_steps++;
2640 mem_bin_count += QUERY_CACHE_MEM_BIN_PARTS_INC;
2641 mem_bin_count = (uint) (mem_bin_count * QUERY_CACHE_MEM_BIN_PARTS_MUL);
2642
2643 // Prevent too small bins spacing
2644 if (mem_bin_count > (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2))
2645 mem_bin_count= (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2);
2646 }
2647 inc = (prev_size - mem_bin_size) / mem_bin_count;
2648 mem_bin_num += (mem_bin_count - (min_allocation_unit - mem_bin_size)/inc);
2649 mem_bin_steps++;
2650 additional_data_size = ((mem_bin_num+1) *
2651 ALIGN_SIZE(sizeof(Query_cache_memory_bin))+
2652 (mem_bin_steps *
2653 ALIGN_SIZE(sizeof(Query_cache_memory_bin_step))));
2654
2655 if (query_cache_size < additional_data_size)
2656 goto err;
2657 query_cache_size -= additional_data_size;
2658
2659 if (!(cache= (uchar *)
2660 my_malloc_lock(query_cache_size+additional_data_size, MYF(0))))
2661 goto err;
2662#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DONTDUMP)
2663 if (madvise(cache, query_cache_size+additional_data_size, MADV_DONTDUMP))
2664 {
2665 DBUG_PRINT("warning", ("coudn't mark query cache memory as MADV_DONTDUMP: %s",
2666 strerror(errno)));
2667 }
2668#endif
2669
2670 DBUG_PRINT("qcache", ("cache length %zu, min unit %zu, %zu bins",
2671 query_cache_size, min_allocation_unit, mem_bin_num));
2672
2673 steps = (Query_cache_memory_bin_step *) cache;
2674 bins = ((Query_cache_memory_bin *)
2675 (cache + mem_bin_steps *
2676 ALIGN_SIZE(sizeof(Query_cache_memory_bin_step))));
2677
2678 first_block = (Query_cache_block *) (cache + additional_data_size);
2679 first_block->init(query_cache_size);
2680 total_blocks++;
2681 first_block->pnext=first_block->pprev=first_block;
2682 first_block->next=first_block->prev=first_block;
2683
2684 /* Prepare bins */
2685
2686 bins[0].init(max_mem_bin_size);
2687 steps[0].init(max_mem_bin_size,0,0);
2688 mem_bin_count = (uint) ((1 + QUERY_CACHE_MEM_BIN_PARTS_INC) *
2689 QUERY_CACHE_MEM_BIN_PARTS_MUL);
2690 num= step= 1;
2691 mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
2692 while (mem_bin_size > min_allocation_unit)
2693 {
2694 size_t incr = (steps[step-1].size - mem_bin_size) / mem_bin_count;
2695 size_t size = mem_bin_size;
2696 for (size_t i= mem_bin_count; i > 0; i--)
2697 {
2698 bins[num+i-1].init(size);
2699 size += incr;
2700 }
2701 num += mem_bin_count;
2702 steps[step].init(mem_bin_size, num-1, incr);
2703 mem_bin_size >>= QUERY_CACHE_MEM_BIN_STEP_PWR2;
2704 step++;
2705 mem_bin_count += QUERY_CACHE_MEM_BIN_PARTS_INC;
2706 mem_bin_count = (uint) (mem_bin_count * QUERY_CACHE_MEM_BIN_PARTS_MUL);
2707 if (mem_bin_count > (mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2))
2708 mem_bin_count=(mem_bin_size >> QUERY_CACHE_MEM_BIN_SPC_LIM_PWR2);
2709 }
2710 inc = (steps[step-1].size - mem_bin_size) / mem_bin_count;
2711
2712 /*
2713 num + mem_bin_count > mem_bin_num, but index never be > mem_bin_num
2714 because block with size < min_allocated_unit never will be requested
2715 */
2716
2717 steps[step].init(mem_bin_size, num + mem_bin_count - 1, inc);
2718 {
2719 size_t skiped = (min_allocation_unit - mem_bin_size)/inc;
2720 size_t size = mem_bin_size + inc*skiped;
2721 size_t i = mem_bin_count - skiped;
2722 while (i-- > 0)
2723 {
2724 bins[num+i].init(size);
2725 size += inc;
2726 }
2727 }
2728 bins[mem_bin_num].number = 1; // For easy end test in get_free_block
2729 free_memory = free_memory_blocks = 0;
2730 insert_into_free_memory_list(first_block);
2731
2732 DUMP(this);
2733
2734 (void) my_hash_init(&queries, &my_charset_bin, def_query_hash_size, 0, 0,
2735 query_cache_query_get_key, 0, 0);
2736#ifndef FN_NO_CASE_SENSE
2737 /*
2738 If lower_case_table_names!=0 then db and table names are already
2739 converted to lower case and we can use binary collation for their
2740 comparison (no matter if file system case sensitive or not).
2741 If we have case-sensitive file system (like on most Unixes) and
2742 lower_case_table_names == 0 then we should distinguish my_table
2743 and MY_TABLE cases and so again can use binary collation.
2744 */
2745 (void) my_hash_init(&tables, &my_charset_bin, def_table_hash_size, 0, 0,
2746 query_cache_table_get_key, 0, 0);
2747#else
2748 /*
2749 On windows, OS/2, MacOS X with HFS+ or any other case insensitive
2750 file system if lower_case_table_names!=0 we have same situation as
2751 in previous case, but if lower_case_table_names==0 then we should
2752 not distinguish cases (to be compatible in behavior with underlying
2753 file system) and so should use case insensitive collation for
2754 comparison.
2755 */
2756 (void) my_hash_init(&tables,
2757 lower_case_table_names ? &my_charset_bin :
2758 files_charset_info,
2759 def_table_hash_size, 0, 0,query_cache_table_get_key,
2760 0, 0);
2761#endif
2762
2763 queries_in_cache = 0;
2764 queries_blocks = 0;
2765 DBUG_RETURN(query_cache_size +
2766 additional_data_size + approx_additional_data_size);
2767
2768err:
2769 make_disabled();
2770 DBUG_RETURN(0);
2771}
2772
2773
2774/* Disable the use of the query cache */
2775
2776void Query_cache::make_disabled()
2777{
2778 DBUG_ENTER("Query_cache::make_disabled");
2779 query_cache_size= 0;
2780 queries_blocks= 0;
2781 free_memory= 0;
2782 free_memory_blocks= 0;
2783 bins= 0;
2784 steps= 0;
2785 cache= 0;
2786 mem_bin_num= mem_bin_steps= 0;
2787 queries_in_cache= 0;
2788 first_block= 0;
2789 total_blocks= 0;
2790 tables_blocks= 0;
2791 DBUG_VOID_RETURN;
2792}
2793
2794
2795/**
2796 @class Query_cache
2797 Free all resources allocated by the cache.
2798
2799 This function frees all resources allocated by the cache. You
2800 have to call init_cache() before using the cache again. This function
2801 requires the cache to be locked (LOCKED_NO_WAIT, lock_and_suspend) or
2802 disabling.
2803*/
2804
2805void Query_cache::free_cache()
2806{
2807 DBUG_ENTER("Query_cache::free_cache");
2808
2809 DBUG_ASSERT(m_cache_lock_status == LOCKED_NO_WAIT ||
2810 m_cache_status == DISABLE_REQUEST);
2811
2812 /* Destroy locks */
2813 Query_cache_block *block= queries_blocks;
2814 if (block)
2815 {
2816 do
2817 {
2818 Query_cache_query *query= block->query();
2819 /*
2820 There will not be new requests but some maybe not finished yet,
2821 so wait for them by trying lock/unlock
2822 */
2823 BLOCK_LOCK_WR(block);
2824 BLOCK_UNLOCK_WR(block);
2825
2826 mysql_rwlock_destroy(&query->lock);
2827 block= block->next;
2828 } while (block != queries_blocks);
2829 }
2830
2831#if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DODUMP)
2832 if (madvise(cache, query_cache_size+additional_data_size, MADV_DODUMP))
2833 {
2834 DBUG_PRINT("warning", ("coudn't mark query cache memory as MADV_DODUMP: %s",
2835 strerror(errno)));
2836 }
2837#endif
2838 my_free(cache);
2839 make_disabled();
2840 my_hash_free(&queries);
2841 my_hash_free(&tables);
2842 DBUG_VOID_RETURN;
2843}
2844
2845/*****************************************************************************
2846 Free block data
2847*****************************************************************************/
2848
2849
2850/**
2851 Flush the cache.
2852
2853 This function will flush cache contents. It assumes we have
2854 'structure_guard_mutex' locked. The function sets the m_cache_status flag and
2855 releases the lock, so other threads may proceed skipping the cache as if it
2856 is disabled. Concurrent flushes are performed in turn.
2857 After flush_cache() call, the cache is flushed, all the freed memory is
2858 accumulated in bin[0], and the 'structure_guard_mutex' is locked. However,
2859 since we could release the mutex during execution, the rest of the cache
2860 state could have been changed, and should not be relied on.
2861*/
2862
2863void Query_cache::flush_cache()
2864{
2865 QC_DEBUG_SYNC("wait_in_query_cache_flush2");
2866
2867 my_hash_reset(&queries);
2868 while (queries_blocks != 0)
2869 {
2870 BLOCK_LOCK_WR(queries_blocks);
2871 free_query_internal(queries_blocks);
2872 }
2873}
2874
2875/*
2876 Free oldest query that is not in use by another thread.
2877 Returns 1 if we couldn't remove anything
2878*/
2879
2880my_bool Query_cache::free_old_query()
2881{
2882 DBUG_ENTER("Query_cache::free_old_query");
2883 if (queries_blocks)
2884 {
2885 /*
2886 try_lock_writing used to prevent client because here lock
2887 sequence is breached.
2888 Also we don't need remove locked queries at this point.
2889 */
2890 Query_cache_block *query_block= 0;
2891 if (queries_blocks != 0)
2892 {
2893 Query_cache_block *block = queries_blocks;
2894 /* Search until we find first query that we can remove */
2895 do
2896 {
2897 Query_cache_query *header = block->query();
2898 if (header->result() != 0 &&
2899 header->result()->type == Query_cache_block::RESULT &&
2900 block->query()->try_lock_writing())
2901 {
2902 query_block = block;
2903 break;
2904 }
2905 } while ((block=block->next) != queries_blocks );
2906 }
2907
2908 if (query_block != 0)
2909 {
2910 free_query(query_block);
2911 lowmem_prunes++;
2912 DBUG_RETURN(0);
2913 }
2914 }
2915 DBUG_RETURN(1); // Nothing to remove
2916}
2917
2918
2919/*
2920 free_query_internal() - free query from query cache.
2921
2922 SYNOPSIS
2923 free_query_internal()
2924 query_block Query_cache_block representing the query
2925
2926 DESCRIPTION
2927 This function will remove the query from a cache, and place its
2928 memory blocks to the list of free blocks. 'query_block' must be
2929 locked for writing, this function will release (and destroy) this
2930 lock.
2931
2932 NOTE
2933 'query_block' should be removed from 'queries' hash _before_
2934 calling this method, as the lock will be destroyed here.
2935*/
2936
2937void Query_cache::free_query_internal(Query_cache_block *query_block)
2938{
2939 DBUG_ENTER("Query_cache::free_query_internal");
2940 DBUG_PRINT("qcache", ("free query %p %zu bytes result",
2941 query_block,
2942 query_block->query()->length() ));
2943
2944 queries_in_cache--;
2945
2946 Query_cache_query *query= query_block->query();
2947
2948 if (query->writer() != 0)
2949 {
2950 /* Tell MySQL that this query should not be cached anymore */
2951 query->writer()->first_query_block= NULL;
2952 query->writer(0);
2953 }
2954 double_linked_list_exclude(query_block, &queries_blocks);
2955 Query_cache_block_table *table= query_block->table(0);
2956
2957 for (TABLE_COUNTER_TYPE i= 0; i < query_block->n_tables; i++)
2958 unlink_table(table++);
2959 Query_cache_block *result_block= query->result();
2960
2961 /*
2962 The following is true when query destruction was called and no results
2963 in query . (query just registered and then abort/pack/flush called)
2964 */
2965 if (result_block != 0)
2966 {
2967 if (result_block->type != Query_cache_block::RESULT)
2968 {
2969 // removing unfinished query
2970 refused++;
2971 inserts--;
2972 }
2973 Query_cache_block *block= result_block;
2974 do
2975 {
2976 Query_cache_block *current= block;
2977 block= block->next;
2978 free_memory_block(current);
2979 } while (block != result_block);
2980 }
2981 else
2982 {
2983 // removing unfinished query
2984 refused++;
2985 inserts--;
2986 }
2987
2988 query->unlock_n_destroy();
2989 free_memory_block(query_block);
2990
2991 DBUG_VOID_RETURN;
2992}
2993
2994
2995/*
2996 free_query() - free query from query cache.
2997
2998 SYNOPSIS
2999 free_query()
3000 query_block Query_cache_block representing the query
3001
3002 DESCRIPTION
3003 This function will remove 'query_block' from 'queries' hash, and
3004 then call free_query_internal(), which see.
3005*/
3006
3007void Query_cache::free_query(Query_cache_block *query_block)
3008{
3009 DBUG_ENTER("Query_cache::free_query");
3010 DBUG_PRINT("qcache", ("free query %p %zu bytes result",
3011 query_block,
3012 query_block->query()->length() ));
3013
3014 my_hash_delete(&queries,(uchar *) query_block);
3015 free_query_internal(query_block);
3016
3017 DBUG_VOID_RETURN;
3018}
3019
3020/*****************************************************************************
3021 Query data creation
3022*****************************************************************************/
3023
3024Query_cache_block *
3025Query_cache::write_block_data(size_t data_len, uchar* data,
3026 size_t header_len,
3027 Query_cache_block::block_type type,
3028 TABLE_COUNTER_TYPE ntab)
3029{
3030 size_t all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
3031 ALIGN_SIZE(ntab*sizeof(Query_cache_block_table)) +
3032 header_len);
3033 size_t len = data_len + all_headers_len;
3034 size_t align_len= ALIGN_SIZE(len);
3035 DBUG_ENTER("Query_cache::write_block_data");
3036 DBUG_PRINT("qcache", ("data: %zd, header: %zd, all header: %zd",
3037 data_len, header_len, all_headers_len));
3038 Query_cache_block *block= allocate_block(MY_MAX(align_len,
3039 min_allocation_unit),1, 0);
3040 if (block != 0)
3041 {
3042 block->type = type;
3043 block->n_tables = ntab;
3044 block->used = len;
3045
3046 memcpy((uchar *) block+ all_headers_len, data, data_len);
3047 }
3048 DBUG_RETURN(block);
3049}
3050
3051
3052my_bool
3053Query_cache::append_result_data(Query_cache_block **current_block,
3054 size_t data_len, uchar* data,
3055 Query_cache_block *query_block)
3056{
3057 DBUG_ENTER("Query_cache::append_result_data");
3058 DBUG_PRINT("qcache", ("append %zu bytes to %p query",
3059 data_len, query_block));
3060
3061 if (query_block->query()->add(data_len) > query_cache_limit)
3062 {
3063 DBUG_PRINT("qcache", ("size limit reached %zu > %zu",
3064 query_block->query()->length(),
3065 query_cache_limit));
3066 DBUG_RETURN(0);
3067 }
3068 if (*current_block == 0)
3069 {
3070 DBUG_PRINT("qcache", ("allocated first result data block %zu", data_len));
3071 DBUG_RETURN(write_result_data(current_block, data_len, data, query_block,
3072 Query_cache_block::RES_BEG));
3073 }
3074 Query_cache_block *last_block = (*current_block)->prev;
3075
3076 DBUG_PRINT("qcache", ("lastblock %p len %zu used %zu",
3077 last_block, last_block->length,
3078 last_block->used));
3079 my_bool success = 1;
3080 size_t last_block_free_space= last_block->length - last_block->used;
3081
3082 /*
3083 We will first allocate and write the 'tail' of data, that doesn't fit
3084 in the 'last_block'. Only if this succeeds, we will fill the last_block.
3085 This saves us a memcpy if the query doesn't fit in the query cache.
3086 */
3087
3088 // Try join blocks if physically next block is free...
3089 size_t tail = data_len - last_block_free_space;
3090 size_t append_min = get_min_append_result_data_size();
3091 if (last_block_free_space < data_len &&
3092 append_next_free_block(last_block,
3093 MY_MAX(tail, append_min)))
3094 last_block_free_space = last_block->length - last_block->used;
3095 // If no space in last block (even after join) allocate new block
3096 if (last_block_free_space < data_len)
3097 {
3098 DBUG_PRINT("qcache", ("allocate new block for %zu bytes",
3099 data_len-last_block_free_space));
3100 Query_cache_block *new_block = 0;
3101 success = write_result_data(&new_block, data_len-last_block_free_space,
3102 (uchar*)(((uchar*)data)+last_block_free_space),
3103 query_block,
3104 Query_cache_block::RES_CONT);
3105 /*
3106 new_block may be != 0 even !success (if write_result_data
3107 allocate a small block but failed to allocate continue)
3108 */
3109 if (new_block != 0)
3110 double_linked_list_join(last_block, new_block);
3111 }
3112 else
3113 {
3114 // It is success (nobody can prevent us write data)
3115 unlock();
3116 }
3117
3118 // Now finally write data to the last block
3119 if (success && last_block_free_space > 0)
3120 {
3121 size_t to_copy = MY_MIN(data_len,last_block_free_space);
3122 DBUG_PRINT("qcache", ("use free space %zub at block %p to copy %zub",
3123 last_block_free_space,last_block, to_copy));
3124 memcpy((uchar*) last_block + last_block->used, data, to_copy);
3125 last_block->used+=to_copy;
3126 }
3127 DBUG_RETURN(success);
3128}
3129
3130
3131my_bool Query_cache::write_result_data(Query_cache_block **result_block,
3132 size_t data_len, uchar* data,
3133 Query_cache_block *query_block,
3134 Query_cache_block::block_type type)
3135{
3136 DBUG_ENTER("Query_cache::write_result_data");
3137 DBUG_PRINT("qcache", ("data_len %zu",data_len));
3138
3139 /*
3140 Reserve block(s) for filling
3141 During data allocation we must have structure_guard_mutex locked.
3142 As data copy is not a fast operation, it's better if we don't have
3143 structure_guard_mutex locked during data coping.
3144 Thus we first allocate space and lock query, then unlock
3145 structure_guard_mutex and copy data.
3146 */
3147
3148 my_bool success = allocate_data_chain(result_block, data_len, query_block,
3149 type == Query_cache_block::RES_BEG);
3150 if (success)
3151 {
3152 // It is success (nobody can prevent us write data)
3153 unlock();
3154 uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
3155 ALIGN_SIZE(sizeof(Query_cache_result)));
3156#ifndef EMBEDDED_LIBRARY
3157 Query_cache_block *block= *result_block;
3158 uchar *rest= data;
3159 // Now fill list of blocks that created by allocate_data_chain
3160 do
3161 {
3162 block->type = type;
3163 size_t length = block->used - headers_len;
3164 DBUG_PRINT("qcache", ("write %zu byte in block %p",length,
3165 block));
3166 memcpy((uchar*) block+headers_len, rest, length);
3167 rest += length;
3168 block = block->next;
3169 type = Query_cache_block::RES_CONT;
3170 } while (block != *result_block);
3171#else
3172 /*
3173 Set type of first block, emb_store_querycache_result() will handle
3174 the others.
3175 */
3176 (*result_block)->type= type;
3177 Querycache_stream qs(*result_block, headers_len);
3178 emb_store_querycache_result(&qs, (THD*)data);
3179#endif /*!EMBEDDED_LIBRARY*/
3180 }
3181 else
3182 {
3183 if (*result_block != 0)
3184 {
3185 // Destroy list of blocks that was created & locked by lock_result_data
3186 Query_cache_block *block = *result_block;
3187 do
3188 {
3189 Query_cache_block *current = block;
3190 block = block->next;
3191 free_memory_block(current);
3192 } while (block != *result_block);
3193 *result_block = 0;
3194 /*
3195 It is not success => not unlock structure_guard_mutex (we need it to
3196 free query)
3197 */
3198 }
3199 }
3200 DBUG_PRINT("qcache", ("success %d", (int) success));
3201 DBUG_RETURN(success);
3202}
3203
3204inline size_t Query_cache::get_min_first_result_data_size()
3205{
3206 if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
3207 return min_result_data_size;
3208 size_t avg_result = (query_cache_size - free_memory) / queries_in_cache;
3209 avg_result = MY_MIN(avg_result, query_cache_limit);
3210 return MY_MAX(min_result_data_size, avg_result);
3211}
3212
3213inline size_t Query_cache::get_min_append_result_data_size()
3214{
3215 return min_result_data_size;
3216}
3217
3218/*
3219 Allocate one or more blocks to hold data
3220*/
3221my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
3222 size_t data_len,
3223 Query_cache_block *query_block,
3224 my_bool first_block_arg)
3225{
3226 size_t all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
3227 ALIGN_SIZE(sizeof(Query_cache_result)));
3228 size_t min_size = (first_block_arg ?
3229 get_min_first_result_data_size():
3230 get_min_append_result_data_size());
3231 Query_cache_block *prev_block= NULL;
3232 Query_cache_block *new_block;
3233 DBUG_ENTER("Query_cache::allocate_data_chain");
3234 DBUG_PRINT("qcache", ("data_len %zu, all_headers_len %zu",
3235 data_len, all_headers_len));
3236
3237 do
3238 {
3239 size_t len= data_len + all_headers_len;
3240 size_t align_len= ALIGN_SIZE(len);
3241
3242 if (!(new_block= allocate_block(MY_MAX(min_size, align_len),
3243 min_result_data_size == 0,
3244 all_headers_len + min_result_data_size)))
3245 {
3246 DBUG_PRINT("warning", ("Can't allocate block for results"));
3247 DBUG_RETURN(FALSE);
3248 }
3249
3250 new_block->n_tables = 0;
3251 new_block->used = MY_MIN(len, new_block->length);
3252 new_block->type = Query_cache_block::RES_INCOMPLETE;
3253 new_block->next = new_block->prev = new_block;
3254 Query_cache_result *header = new_block->result();
3255 header->parent(query_block);
3256
3257 DBUG_PRINT("qcache", ("Block len %zu used %zu",
3258 new_block->length, new_block->used));
3259
3260 if (prev_block)
3261 double_linked_list_join(prev_block, new_block);
3262 else
3263 *result_block= new_block;
3264 if (new_block->length >= len)
3265 break;
3266
3267 /*
3268 We got less memory then we need (no big memory blocks) =>
3269 Continue to allocated more blocks until we got everything we need.
3270 */
3271 data_len= len - new_block->length;
3272 prev_block= new_block;
3273 } while (1);
3274
3275 DBUG_RETURN(TRUE);
3276}
3277
3278/*****************************************************************************
3279 Tables management
3280*****************************************************************************/
3281
3282/*
3283 Invalidate the first table in the table_list
3284*/
3285
3286void Query_cache::invalidate_table(THD *thd, TABLE_LIST *table_list)
3287{
3288 if (table_list->table != 0)
3289 invalidate_table(thd, table_list->table); // Table is open
3290 else
3291 {
3292 const char *key;
3293 uint key_length;
3294 key_length= get_table_def_key(table_list, &key);
3295
3296 // We don't store temporary tables => no key_length+=4 ...
3297 invalidate_table(thd, (uchar *)key, key_length);
3298 }
3299}
3300
3301void Query_cache::invalidate_table(THD *thd, TABLE *table)
3302{
3303 invalidate_table(thd, (uchar*) table->s->table_cache_key.str,
3304 table->s->table_cache_key.length);
3305}
3306
3307void Query_cache::invalidate_table(THD *thd, uchar * key, size_t key_length)
3308{
3309 DEBUG_SYNC(thd, "wait_in_query_cache_invalidate1");
3310
3311 /*
3312 Lock the query cache and queue all invalidation attempts to avoid
3313 the risk of a race between invalidation, cache inserts and flushes.
3314 */
3315 lock(thd);
3316
3317 DEBUG_SYNC(thd, "wait_in_query_cache_invalidate2");
3318
3319 if (query_cache_size > 0)
3320 invalidate_table_internal(thd, key, key_length);
3321
3322 unlock();
3323}
3324
3325
3326/**
3327 Try to locate and invalidate a table by name.
3328 The caller must ensure that no other thread is trying to work with
3329 the query cache when this function is executed.
3330
3331 @pre structure_guard_mutex is acquired or LOCKED is set.
3332*/
3333
3334void
3335Query_cache::invalidate_table_internal(THD *thd, uchar *key, size_t key_length)
3336{
3337 Query_cache_block *table_block=
3338 (Query_cache_block*)my_hash_search(&tables, key, key_length);
3339 if (table_block)
3340 {
3341 Query_cache_block_table *list_root= table_block->table(0);
3342 invalidate_query_block_list(thd, list_root);
3343 }
3344}
3345
3346/**
3347 Invalidate a linked list of query cache blocks.
3348
3349 Each block tries to acquire a block level lock before
3350 free_query is a called. This function will in turn affect
3351 related table- and result-blocks.
3352
3353 @param[in,out] thd Thread context.
3354 @param[in,out] list_root A pointer to a circular list of query blocks.
3355
3356*/
3357
3358void
3359Query_cache::invalidate_query_block_list(THD *thd,
3360 Query_cache_block_table *list_root)
3361{
3362 while (list_root->next != list_root)
3363 {
3364 Query_cache_block *query_block= list_root->next->block();
3365 BLOCK_LOCK_WR(query_block);
3366 free_query(query_block);
3367 }
3368}
3369
3370/*
3371 Register given table list beginning with given position in tables table of
3372 block
3373
3374 SYNOPSIS
3375 Query_cache::register_tables_from_list
3376 thd thread handle
3377 tables_used given table list
3378 counter number current position in table of tables of block
3379 block_table pointer to current position in tables table of block
3380
3381 RETURN
3382 0 error
3383 number of next position of table entry in table of tables of block
3384*/
3385
3386TABLE_COUNTER_TYPE
3387Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used,
3388 TABLE_COUNTER_TYPE counter,
3389 Query_cache_block_table **block_table)
3390{
3391 TABLE_COUNTER_TYPE n;
3392 DBUG_ENTER("Query_cache::register_tables_from_list");
3393 for (n= counter;
3394 tables_used;
3395 tables_used= tables_used->next_global, n++, (*block_table)++)
3396 {
3397 if (tables_used->is_anonymous_derived_table())
3398 {
3399 DBUG_PRINT("qcache", ("derived table skipped"));
3400 n--;
3401 (*block_table)--;
3402 continue;
3403 }
3404 (*block_table)->n= n;
3405 if (tables_used->view)
3406 {
3407 const char *key;
3408 uint key_length;
3409 DBUG_PRINT("qcache", ("view: %s db: %s",
3410 tables_used->view_name.str,
3411 tables_used->view_db.str));
3412 key_length= get_table_def_key(tables_used, &key);
3413 /*
3414 There are not callback function for for VIEWs
3415 */
3416 if (!insert_table(thd, key_length, key, (*block_table),
3417 tables_used->view_db.length, 0,
3418 HA_CACHE_TBL_NONTRANSACT, 0, 0, TRUE))
3419 DBUG_RETURN(0);
3420 /*
3421 We do not need to register view tables here because they are already
3422 present in the global list.
3423 */
3424 }
3425 else
3426 {
3427 DBUG_PRINT("qcache",
3428 ("table: %s db: %s openinfo: %p keylen: %zu key: %p",
3429 tables_used->table->s->table_name.str,
3430 tables_used->table->s->table_cache_key.str,
3431 tables_used->table,
3432 tables_used->table->s->table_cache_key.length,
3433 tables_used->table->s->table_cache_key.str));
3434
3435 if (!insert_table(thd, tables_used->table->s->table_cache_key.length,
3436 tables_used->table->s->table_cache_key.str,
3437 (*block_table),
3438 tables_used->db.length, 0,
3439 tables_used->table->file->table_cache_type(),
3440 tables_used->callback_func,
3441 tables_used->engine_data,
3442 TRUE))
3443 DBUG_RETURN(0);
3444
3445 if (tables_used->table->file->
3446 register_query_cache_dependant_tables(thd, this, block_table, &n))
3447 DBUG_RETURN(0);
3448 }
3449 }
3450 DBUG_RETURN(n - counter);
3451}
3452
3453/*
3454 Store all used tables
3455
3456 SYNOPSIS
3457 register_all_tables()
3458 thd Thread handle
3459 block Store tables in this block
3460 tables_used List if used tables
3461 tables_arg Not used ?
3462*/
3463
3464my_bool Query_cache::register_all_tables(THD *thd,
3465 Query_cache_block *block,
3466 TABLE_LIST *tables_used,
3467 TABLE_COUNTER_TYPE tables_arg)
3468{
3469 TABLE_COUNTER_TYPE n;
3470 DBUG_PRINT("qcache", ("register tables block %p, n %d, header %x",
3471 block, (int) tables_arg,
3472 (int) ALIGN_SIZE(sizeof(Query_cache_block))));
3473
3474 Query_cache_block_table *block_table = block->table(0);
3475
3476 n= register_tables_from_list(thd, tables_used, 0, &block_table);
3477
3478 if (n==0)
3479 {
3480 /* Unlink the tables we allocated above */
3481 for (Query_cache_block_table *tmp = block->table(0) ;
3482 tmp != block_table;
3483 tmp++)
3484 unlink_table(tmp);
3485 if (block_table->parent)
3486 unlink_table(block_table);
3487 }
3488 return MY_TEST(n);
3489}
3490
3491
3492/**
3493 Insert used table name into the cache.
3494
3495 @return Error status
3496 @retval FALSE On error
3497 @retval TRUE On success
3498*/
3499
3500my_bool
3501Query_cache::insert_table(THD *thd, size_t key_len, const char *key,
3502 Query_cache_block_table *node, size_t db_length, uint8 suffix_length_arg,
3503 uint8 cache_type,
3504 qc_engine_callback callback,
3505 ulonglong engine_data,
3506 my_bool hash)
3507{
3508 DBUG_ENTER("Query_cache::insert_table");
3509 DBUG_PRINT("qcache", ("insert table node %p, len %zu",
3510 node, key_len));
3511
3512 Query_cache_block *table_block=
3513 (hash ?
3514 (Query_cache_block *) my_hash_search(&tables, (uchar*) key, key_len) :
3515 NULL);
3516
3517 if (table_block &&
3518 table_block->table()->engine_data() != engine_data)
3519 {
3520 DBUG_PRINT("qcache",
3521 ("Handler require invalidation queries of %s.%s %llu-%llu",
3522 table_block->table()->db(),
3523 table_block->table()->table(),
3524 engine_data,
3525 table_block->table()->engine_data()));
3526 /*
3527 as far as we delete all queries with this table, table block will be
3528 deleted, too
3529 */
3530 {
3531 Query_cache_block_table *list_root= table_block->table(0);
3532 invalidate_query_block_list(thd, list_root);
3533 }
3534
3535 table_block= 0;
3536 }
3537
3538 if (table_block == 0)
3539 {
3540 DBUG_PRINT("qcache", ("new table block from %p (%u)",
3541 key, (int) key_len));
3542 table_block= write_block_data(key_len, (uchar*) key,
3543 ALIGN_SIZE(sizeof(Query_cache_table)),
3544 Query_cache_block::TABLE, 1);
3545 if (table_block == 0)
3546 {
3547 DBUG_PRINT("qcache", ("Can't write table name to cache"));
3548 DBUG_RETURN(0);
3549 }
3550 Query_cache_table *header= table_block->table();
3551 double_linked_list_simple_include(table_block,
3552 &tables_blocks);
3553 /*
3554 First node in the Query_cache_block_table-chain is the table-type
3555 block. This block will only have one Query_cache_block_table (n=0).
3556 */
3557 Query_cache_block_table *list_root= table_block->table(0);
3558 list_root->n= 0;
3559
3560 /*
3561 The node list is circular in nature.
3562 */
3563 list_root->next= list_root->prev= list_root;
3564
3565 if (hash &&
3566 my_hash_insert(&tables, (const uchar *) table_block))
3567 {
3568 DBUG_PRINT("qcache", ("Can't insert table to hash"));
3569 // write_block_data return locked block
3570 free_memory_block(table_block);
3571 DBUG_RETURN(0);
3572 }
3573 char *db= header->db();
3574 header->table(db + db_length + 1);
3575 header->key_length((uint32)key_len);
3576 header->suffix_length(suffix_length_arg);
3577 header->type(cache_type);
3578 header->callback(callback);
3579 header->engine_data(engine_data);
3580 header->set_hashed(hash);
3581
3582 /*
3583 We insert this table without the assumption that it isn't refrenenced by
3584 any queries.
3585 */
3586 header->m_cached_query_count= 0;
3587 }
3588
3589 /*
3590 Table is now in the cache; link the table_block-node associated
3591 with the currently processed query into the chain of queries depending
3592 on the cached table.
3593 */
3594 Query_cache_block_table *list_root= table_block->table(0);
3595 node->next= list_root->next;
3596 list_root->next= node;
3597 node->next->prev= node;
3598 node->prev= list_root;
3599 node->parent= table_block->table();
3600 /*
3601 Increase the counter to keep track on how long this chain
3602 of queries is.
3603 */
3604 Query_cache_table *table_block_data= table_block->table();
3605 table_block_data->m_cached_query_count++;
3606 DBUG_RETURN(1);
3607}
3608
3609
3610void Query_cache::unlink_table(Query_cache_block_table *node)
3611{
3612 DBUG_ENTER("Query_cache::unlink_table");
3613 node->prev->next= node->next;
3614 node->next->prev= node->prev;
3615 Query_cache_block_table *neighbour= node->next;
3616 Query_cache_table *table_block_data= node->parent;
3617 table_block_data->m_cached_query_count--;
3618
3619 DBUG_ASSERT(table_block_data->m_cached_query_count >= 0);
3620
3621 if (neighbour->next == neighbour)
3622 {
3623 DBUG_ASSERT(table_block_data->m_cached_query_count == 0);
3624 /*
3625 If neighbor is root of list, the list is empty.
3626 The root of the list is always a table-type block
3627 which contain exactly one Query_cache_block_table
3628 node object, thus we can use the block() method
3629 to calculate the Query_cache_block address.
3630 */
3631 Query_cache_block *table_block= neighbour->block();
3632 double_linked_list_exclude(table_block,
3633 &tables_blocks);
3634 Query_cache_table *header= table_block->table();
3635 if (header->is_hashed())
3636 my_hash_delete(&tables,(uchar *) table_block);
3637 free_memory_block(table_block);
3638 }
3639 DBUG_VOID_RETURN;
3640}
3641
3642/*****************************************************************************
3643 Free memory management
3644*****************************************************************************/
3645
3646Query_cache_block *
3647Query_cache::allocate_block(size_t len, my_bool not_less, size_t min)
3648{
3649 DBUG_ENTER("Query_cache::allocate_block");
3650 DBUG_PRINT("qcache", ("len %zu, not less %d, min %zu",
3651 len, not_less,min));
3652
3653 if (len >= MY_MIN(query_cache_size, query_cache_limit))
3654 {
3655 DBUG_PRINT("qcache", ("Query cache hase only %zu memory and limit %zu",
3656 query_cache_size, query_cache_limit));
3657 DBUG_RETURN(0); // in any case we don't have such piece of memory
3658 }
3659
3660 /* Free old queries until we have enough memory to store this block */
3661 Query_cache_block *block;
3662 do
3663 {
3664 block= get_free_block(len, not_less, min);
3665 }
3666 while (block == 0 && !free_old_query());
3667
3668 if (block != 0) // If we found a suitable block
3669 {
3670 if (block->length >= ALIGN_SIZE(len) + min_allocation_unit)
3671 split_block(block,ALIGN_SIZE(len));
3672 }
3673
3674 DBUG_RETURN(block);
3675}
3676
3677
3678Query_cache_block *
3679Query_cache::get_free_block(size_t len, my_bool not_less, size_t min)
3680{
3681 Query_cache_block *block = 0, *first = 0;
3682 DBUG_ENTER("Query_cache::get_free_block");
3683 DBUG_PRINT("qcache",("length %zu, not_less %d, min %zu", len,
3684 (int)not_less, min));
3685
3686 /* Find block with minimal size > len */
3687 uint start = find_bin(len);
3688 // try matching bin
3689 if (bins[start].number != 0)
3690 {
3691 Query_cache_block *list = bins[start].free_blocks;
3692 if (list->prev->length >= len) // check block with max size
3693 {
3694 first = list;
3695 uint n = 0;
3696 while ( n < QUERY_CACHE_MEM_BIN_TRY &&
3697 first->length < len) //we don't need irst->next != list
3698 {
3699 first=first->next;
3700 n++;
3701 }
3702 if (first->length >= len)
3703 block=first;
3704 else // we don't need if (first->next != list)
3705 {
3706 n = 0;
3707 block = list->prev;
3708 while (n < QUERY_CACHE_MEM_BIN_TRY &&
3709 block->length > len)
3710 {
3711 block=block->prev;
3712 n++;
3713 }
3714 if (block->length < len)
3715 block=block->next;
3716 }
3717 }
3718 else
3719 first = list->prev;
3720 }
3721 if (block == 0 && start > 0)
3722 {
3723 DBUG_PRINT("qcache",("Try bins with bigger block size"));
3724 // Try more big bins
3725 int i = start - 1;
3726 while (i > 0 && bins[i].number == 0)
3727 i--;
3728 if (bins[i].number > 0)
3729 block = bins[i].free_blocks;
3730 }
3731
3732 // If no big blocks => try less size (if it is possible)
3733 if (block == 0 && ! not_less)
3734 {
3735 DBUG_PRINT("qcache",("Try to allocate a smaller block"));
3736 if (first != 0 && first->length > min)
3737 block = first;
3738 else
3739 {
3740 uint i = start + 1;
3741 /* bins[mem_bin_num].number contains 1 for easy end test */
3742 for (i= start+1 ; bins[i].number == 0 ; i++) ;
3743 if (i < mem_bin_num && bins[i].free_blocks->prev->length >= min)
3744 block = bins[i].free_blocks->prev;
3745 }
3746 }
3747 if (block != 0)
3748 exclude_from_free_memory_list(block);
3749
3750 DBUG_PRINT("qcache",("getting block %p", block));
3751 DBUG_RETURN(block);
3752}
3753
3754
3755void Query_cache::free_memory_block(Query_cache_block *block)
3756{
3757 DBUG_ENTER("Query_cache::free_memory_block");
3758 block->used=0;
3759 block->type= Query_cache_block::FREE; // mark block as free in any case
3760 DBUG_PRINT("qcache",
3761 ("first_block %p, block %p, pnext %p pprev %p",
3762 first_block, block, block->pnext,
3763 block->pprev));
3764
3765 if (block->pnext != first_block && block->pnext->is_free())
3766 block = join_free_blocks(block, block->pnext);
3767 if (block != first_block && block->pprev->is_free())
3768 block = join_free_blocks(block->pprev, block->pprev);
3769 insert_into_free_memory_list(block);
3770 DBUG_VOID_RETURN;
3771}
3772
3773
3774void Query_cache::split_block(Query_cache_block *block, size_t len)
3775{
3776 DBUG_ENTER("Query_cache::split_block");
3777 Query_cache_block *new_block = (Query_cache_block*)(((uchar*) block)+len);
3778
3779 new_block->init(block->length - len);
3780 total_blocks++;
3781 block->length=len;
3782 new_block->pnext = block->pnext;
3783 block->pnext = new_block;
3784 new_block->pprev = block;
3785 new_block->pnext->pprev = new_block;
3786
3787 if (block->type == Query_cache_block::FREE)
3788 {
3789 // if block was free then it already joined with all free neighbours
3790 insert_into_free_memory_list(new_block);
3791 }
3792 else
3793 free_memory_block(new_block);
3794
3795 DBUG_PRINT("qcache", ("split %p (%zu) new %p",
3796 block, len, new_block));
3797 DBUG_VOID_RETURN;
3798}
3799
3800
3801Query_cache_block *
3802Query_cache::join_free_blocks(Query_cache_block *first_block_arg,
3803 Query_cache_block *block_in_list)
3804{
3805 Query_cache_block *second_block;
3806 DBUG_ENTER("Query_cache::join_free_blocks");
3807 DBUG_PRINT("qcache",
3808 ("join first %p, pnext %p, in list %p",
3809 first_block_arg, first_block_arg->pnext,
3810 block_in_list));
3811
3812 exclude_from_free_memory_list(block_in_list);
3813 second_block = first_block_arg->pnext;
3814 // May be was not free block
3815 second_block->used=0;
3816 second_block->destroy();
3817 total_blocks--;
3818
3819 first_block_arg->length += second_block->length;
3820 first_block_arg->pnext = second_block->pnext;
3821 second_block->pnext->pprev = first_block_arg;
3822
3823 DBUG_RETURN(first_block_arg);
3824}
3825
3826
3827my_bool Query_cache::append_next_free_block(Query_cache_block *block,
3828 size_t add_size)
3829{
3830 Query_cache_block *next_block = block->pnext;
3831 DBUG_ENTER("Query_cache::append_next_free_block");
3832 DBUG_PRINT("enter", ("block %p, add_size %zu", block,
3833 add_size));
3834
3835 if (next_block != first_block && next_block->is_free())
3836 {
3837 size_t old_len = block->length;
3838 exclude_from_free_memory_list(next_block);
3839 next_block->destroy();
3840 total_blocks--;
3841
3842 block->length += next_block->length;
3843 block->pnext = next_block->pnext;
3844 next_block->pnext->pprev = block;
3845
3846 if (block->length > ALIGN_SIZE(old_len + add_size) + min_allocation_unit)
3847 split_block(block,ALIGN_SIZE(old_len + add_size));
3848 DBUG_PRINT("exit", ("block was appended"));
3849 DBUG_RETURN(1);
3850 }
3851 DBUG_RETURN(0);
3852}
3853
3854
3855void Query_cache::exclude_from_free_memory_list(Query_cache_block *free_block)
3856{
3857 DBUG_ENTER("Query_cache::exclude_from_free_memory_list");
3858 Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
3859 free_block->data());
3860 double_linked_list_exclude(free_block, &bin->free_blocks);
3861 bin->number--;
3862 free_memory-=free_block->length;
3863 free_memory_blocks--;
3864 DBUG_PRINT("qcache",("exclude block %p, bin %p", free_block,
3865 bin));
3866 DBUG_VOID_RETURN;
3867}
3868
3869void Query_cache::insert_into_free_memory_list(Query_cache_block *free_block)
3870{
3871 DBUG_ENTER("Query_cache::insert_into_free_memory_list");
3872 uint idx = find_bin(free_block->length);
3873 insert_into_free_memory_sorted_list(free_block, &bins[idx].free_blocks);
3874 /*
3875 We have enough memory in block for storing bin reference due to
3876 min_allocation_unit choice
3877 */
3878 Query_cache_memory_bin **bin_ptr = ((Query_cache_memory_bin**)
3879 free_block->data());
3880 *bin_ptr = bins+idx;
3881 (*bin_ptr)->number++;
3882 DBUG_PRINT("qcache",("insert block %p, bin[%d] %p",
3883 free_block, idx, *bin_ptr));
3884 DBUG_VOID_RETURN;
3885}
3886
3887uint Query_cache::find_bin(size_t size)
3888{
3889 DBUG_ENTER("Query_cache::find_bin");
3890 // Binary search
3891 size_t left = 0, right = mem_bin_steps;
3892 do
3893 {
3894 size_t middle = (left + right) / 2;
3895 if (steps[middle].size > size)
3896 left = middle+1;
3897 else
3898 right = middle;
3899 } while (left < right);
3900 if (left == 0)
3901 {
3902 // first bin not subordinate of common rules
3903 DBUG_PRINT("qcache", ("first bin (# 0), size %zu",size));
3904 DBUG_RETURN(0);
3905 }
3906 size_t bin = steps[left].idx -
3907 ((size - steps[left].size)/steps[left].increment);
3908
3909 DBUG_PRINT("qcache", ("bin %zu step %zu, size %zu step size %zu",
3910 bin, left, size, steps[left].size));
3911 DBUG_RETURN((uint)bin);
3912}
3913
3914
3915/*****************************************************************************
3916 Lists management
3917*****************************************************************************/
3918
3919void Query_cache::move_to_query_list_end(Query_cache_block *query_block)
3920{
3921 DBUG_ENTER("Query_cache::move_to_query_list_end");
3922 double_linked_list_exclude(query_block, &queries_blocks);
3923 double_linked_list_simple_include(query_block, &queries_blocks);
3924 DBUG_VOID_RETURN;
3925}
3926
3927
3928void Query_cache::insert_into_free_memory_sorted_list(Query_cache_block *
3929 new_block,
3930 Query_cache_block **
3931 list)
3932{
3933 DBUG_ENTER("Query_cache::insert_into_free_memory_sorted_list");
3934 /*
3935 list sorted by size in ascendant order, because we need small blocks
3936 more frequently than bigger ones
3937 */
3938
3939 new_block->used = 0;
3940 new_block->n_tables = 0;
3941 new_block->type = Query_cache_block::FREE;
3942
3943 if (*list == 0)
3944 {
3945 *list = new_block->next=new_block->prev=new_block;
3946 DBUG_PRINT("qcache", ("inserted into empty list"));
3947 }
3948 else
3949 {
3950 Query_cache_block *point = *list;
3951 if (point->length >= new_block->length)
3952 {
3953 point = point->prev;
3954 *list = new_block;
3955 }
3956 else
3957 {
3958 /* Find right position in sorted list to put block */
3959 while (point->next != *list &&
3960 point->next->length < new_block->length)
3961 point=point->next;
3962 }
3963 new_block->prev = point;
3964 new_block->next = point->next;
3965 new_block->next->prev = new_block;
3966 point->next = new_block;
3967 }
3968 free_memory+=new_block->length;
3969 free_memory_blocks++;
3970 DBUG_VOID_RETURN;
3971}
3972
3973
3974void
3975Query_cache::double_linked_list_simple_include(Query_cache_block *point,
3976 Query_cache_block **
3977 list_pointer)
3978{
3979 DBUG_ENTER("Query_cache::double_linked_list_simple_include");
3980 DBUG_PRINT("qcache", ("including block %p", point));
3981 if (*list_pointer == 0)
3982 *list_pointer=point->next=point->prev=point;
3983 else
3984 {
3985 // insert to the end of list
3986 point->next = (*list_pointer);
3987 point->prev = (*list_pointer)->prev;
3988 point->prev->next = point;
3989 (*list_pointer)->prev = point;
3990 }
3991 DBUG_VOID_RETURN;
3992}
3993
3994void
3995Query_cache::double_linked_list_exclude(Query_cache_block *point,
3996 Query_cache_block **list_pointer)
3997{
3998 DBUG_ENTER("Query_cache::double_linked_list_exclude");
3999 DBUG_PRINT("qcache", ("excluding block %p, list %p",
4000 point, list_pointer));
4001 if (point->next == point)
4002 *list_pointer = 0; // empty list
4003 else
4004 {
4005 point->next->prev = point->prev;
4006 point->prev->next = point->next;
4007 /*
4008 If the root is removed; select a new root
4009 */
4010 if (point == *list_pointer)
4011 *list_pointer= point->next;
4012 }
4013 DBUG_VOID_RETURN;
4014}
4015
4016
4017void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
4018 Query_cache_block *tail_head)
4019{
4020 Query_cache_block *head_head = head_tail->next,
4021 *tail_tail = tail_head->prev;
4022 head_head->prev = tail_tail;
4023 head_tail->next = tail_head;
4024 tail_head->prev = head_tail;
4025 tail_tail->next = head_head;
4026}
4027
4028/*****************************************************************************
4029 Query
4030*****************************************************************************/
4031
4032/*
4033 Collect information about table types, check that tables are cachable and
4034 count them
4035
4036 SYNOPSIS
4037 process_and_count_tables()
4038 tables_used table list for processing
4039 tables_type pointer to variable for table types collection
4040
4041 RETURN
4042 0 error
4043 >0 number of tables
4044*/
4045
4046TABLE_COUNTER_TYPE
4047Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
4048 uint8 *tables_type)
4049{
4050 DBUG_ENTER("process_and_count_tables");
4051 TABLE_COUNTER_TYPE table_count = 0;
4052 for (; tables_used; tables_used= tables_used->next_global)
4053 {
4054 table_count++;
4055#ifndef NO_EMBEDDED_ACCESS_CHECKS
4056 /*
4057 Disable any attempt to store this statement if there are
4058 column level grants on any referenced tables.
4059 The grant.want_privileges flag was set to 1 in the
4060 check_grant() function earlier if the TABLE_LIST object
4061 had any associated column privileges.
4062
4063 We need to check that the TABLE_LIST object isn't part
4064 of a VIEW definition because we want to be able to cache
4065 views.
4066
4067 TODO: Although it is possible to cache views, the privilege
4068 check on view tables always fall back on column privileges
4069 even if there are more generic table privileges. Thus it isn't
4070 currently possible to retrieve cached view-tables unless the
4071 client has the super user privileges.
4072 */
4073 if (tables_used->grant.want_privilege &&
4074 tables_used->belong_to_view == NULL)
4075 {
4076 DBUG_PRINT("qcache", ("Don't cache statement as it refers to "
4077 "tables with column privileges."));
4078 thd->query_cache_is_applicable= 0; // Query can't be cached
4079 thd->lex->safe_to_cache_query= 0; // For prepared statements
4080 DBUG_RETURN(0);
4081 }
4082#endif
4083 if (tables_used->view)
4084 {
4085 DBUG_PRINT("qcache", ("view: %s db: %s",
4086 tables_used->view_name.str,
4087 tables_used->view_db.str));
4088 *tables_type|= HA_CACHE_TBL_NONTRANSACT;
4089 continue;
4090 }
4091 if (tables_used->derived)
4092 {
4093 DBUG_PRINT("qcache", ("table: %s", tables_used->alias.str));
4094 table_count--;
4095 DBUG_PRINT("qcache", ("derived table skipped"));
4096 continue;
4097 }
4098
4099 DBUG_PRINT("qcache", ("table: %s db: %s type: %u",
4100 tables_used->table->s->table_name.str,
4101 tables_used->table->s->db.str,
4102 tables_used->table->s->db_type()->db_type));
4103 *tables_type|= tables_used->table->file->table_cache_type();
4104
4105 /*
4106 table_alias_charset used here because it depends of
4107 lower_case_table_names variable
4108 */
4109 table_count+= tables_used->table->file->
4110 count_query_cache_dependant_tables(tables_type);
4111
4112 if (tables_used->table->s->not_usable_by_query_cache)
4113 {
4114 DBUG_PRINT("qcache",
4115 ("select not cacheable: temporary, system or "
4116 "other non-cacheable table(s)"));
4117 DBUG_RETURN(0);
4118 }
4119 }
4120 DBUG_RETURN(table_count);
4121}
4122
4123
4124/*
4125In non-embedded QC intercepts result in net_real_write
4126but if we have no net.vio then net_real_write
4127will not be called, so QC can't get results of the query
4128*/
4129#ifdef EMBEDDED_LIBRARY
4130#define qc_is_able_to_intercept_result(T) 1
4131#else
4132#define qc_is_able_to_intercept_result(T) ((T)->net.vio)
4133#endif
4134
4135
4136/*
4137 If query is cacheable return number tables in query
4138 (query without tables are not cached)
4139*/
4140
4141TABLE_COUNTER_TYPE
4142Query_cache::is_cacheable(THD *thd, LEX *lex,
4143 TABLE_LIST *tables_used, uint8 *tables_type)
4144{
4145 TABLE_COUNTER_TYPE table_count;
4146 DBUG_ENTER("Query_cache::is_cacheable");
4147
4148 if (thd->lex->safe_to_cache_query &&
4149 (thd->variables.query_cache_type == 1 ||
4150 (thd->variables.query_cache_type == 2 && (lex->select_lex.options &
4151 OPTION_TO_QUERY_CACHE))) &&
4152 qc_is_able_to_intercept_result(thd))
4153 {
4154 DBUG_PRINT("qcache", ("options: %lx %lx type: %u",
4155 (long) OPTION_TO_QUERY_CACHE,
4156 (long) lex->select_lex.options,
4157 (int) thd->variables.query_cache_type));
4158
4159 if (!(table_count= process_and_count_tables(thd, tables_used,
4160 tables_type)))
4161 DBUG_RETURN(0);
4162
4163 if (thd->in_multi_stmt_transaction_mode() &&
4164 ((*tables_type)&HA_CACHE_TBL_TRANSACT))
4165 {
4166 DBUG_PRINT("qcache", ("not in autocommin mode"));
4167 DBUG_RETURN(0);
4168 }
4169 DBUG_PRINT("qcache", ("select is using %d tables", table_count));
4170 DBUG_RETURN(table_count);
4171 }
4172
4173 DBUG_PRINT("qcache",
4174 ("not interesting query: %d or not cacheable, options %lx %lx type: %u net->vio present: %u",
4175 (int) lex->sql_command,
4176 (long) OPTION_TO_QUERY_CACHE,
4177 (long) lex->select_lex.options,
4178 (int) thd->variables.query_cache_type,
4179 (uint) MY_TEST(qc_is_able_to_intercept_result(thd))));
4180 DBUG_RETURN(0);
4181}
4182
4183/*
4184 Check handler allowance to cache query with these tables
4185
4186 SYNOPSYS
4187 Query_cache::ask_handler_allowance()
4188 thd - thread handlers
4189 tables_used - tables list used in query
4190
4191 RETURN
4192 0 - caching allowed
4193 1 - caching disallowed
4194*/
4195my_bool Query_cache::ask_handler_allowance(THD *thd,
4196 TABLE_LIST *tables_used)
4197{
4198 DBUG_ENTER("Query_cache::ask_handler_allowance");
4199
4200 for (; tables_used; tables_used= tables_used->next_global)
4201 {
4202 TABLE *table;
4203 handler *handler;
4204 if (!(table= tables_used->table))
4205 continue;
4206 handler= table->file;
4207 if (!handler->register_query_cache_table(thd,
4208 table->s->normalized_path.str,
4209 (uint)table->s->normalized_path.length,
4210 &tables_used->callback_func,
4211 &tables_used->engine_data))
4212 {
4213 DBUG_PRINT("qcache", ("Handler does not allow caching for %s",
4214 table->s->normalized_path.str));
4215 /*
4216 As this can change from call to call, don't reset set
4217 thd->lex->safe_to_cache_query
4218 */
4219 thd->query_cache_is_applicable= 0; // Query can't be cached
4220 DBUG_RETURN(1);
4221 }
4222 }
4223 DBUG_RETURN(0);
4224}
4225
4226
4227/*****************************************************************************
4228 Packing
4229*****************************************************************************/
4230
4231
4232/**
4233 Rearrange all memory blocks so that free memory joins at the
4234 'bottom' of the allocated memory block containing all cache data.
4235 @see Query_cache::pack(size_t join_limit, uint iteration_limit)
4236*/
4237
4238void Query_cache::pack_cache()
4239{
4240 DBUG_ENTER("Query_cache::pack_cache");
4241
4242 DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
4243
4244 uchar *border = 0;
4245 Query_cache_block *before = 0;
4246 size_t gap = 0;
4247 my_bool ok = 1;
4248 Query_cache_block *block = first_block;
4249 DUMP(this);
4250
4251 if (first_block)
4252 {
4253 do
4254 {
4255 Query_cache_block *next=block->pnext;
4256 ok = move_by_type(&border, &before, &gap, block);
4257 block = next;
4258 } while (ok && block != first_block);
4259
4260 if (border != 0)
4261 {
4262 Query_cache_block *new_block = (Query_cache_block *) border;
4263 new_block->init(gap);
4264 total_blocks++;
4265 new_block->pnext = before->pnext;
4266 before->pnext = new_block;
4267 new_block->pprev = before;
4268 new_block->pnext->pprev = new_block;
4269 insert_into_free_memory_list(new_block);
4270 }
4271 DUMP(this);
4272 }
4273
4274 DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
4275 DBUG_VOID_RETURN;
4276}
4277
4278
4279my_bool Query_cache::move_by_type(uchar **border,
4280 Query_cache_block **before, size_t *gap,
4281 Query_cache_block *block)
4282{
4283 DBUG_ENTER("Query_cache::move_by_type");
4284
4285 my_bool ok = 1;
4286 switch (block->type) {
4287 case Query_cache_block::FREE:
4288 {
4289 DBUG_PRINT("qcache", ("block %p FREE", block));
4290 if (*border == 0)
4291 {
4292 *border = (uchar *) block;
4293 *before = block->pprev;
4294 DBUG_PRINT("qcache", ("gap beginning here"));
4295 }
4296 exclude_from_free_memory_list(block);
4297 *gap +=block->length;
4298 block->pprev->pnext=block->pnext;
4299 block->pnext->pprev=block->pprev;
4300 block->destroy();
4301 total_blocks--;
4302 DBUG_PRINT("qcache", ("added to gap (%zu)", *gap));
4303 break;
4304 }
4305 case Query_cache_block::TABLE:
4306 {
4307 HASH_SEARCH_STATE record_idx;
4308 DBUG_PRINT("qcache", ("block %p TABLE", block));
4309 if (*border == 0)
4310 break;
4311 size_t len = block->length, used = block->used;
4312 Query_cache_block_table *list_root = block->table(0);
4313 Query_cache_block_table *tprev = list_root->prev,
4314 *tnext = list_root->next;
4315 Query_cache_block *prev = block->prev,
4316 *next = block->next,
4317 *pprev = block->pprev,
4318 *pnext = block->pnext,
4319 *new_block =(Query_cache_block *) *border;
4320 size_t tablename_offset = block->table()->table() - block->table()->db();
4321 char *data = (char*) block->data();
4322 uchar *key;
4323 size_t key_length;
4324 key=query_cache_table_get_key((uchar*) block, &key_length, 0);
4325 my_hash_first(&tables, (uchar*) key, key_length, &record_idx);
4326
4327 block->destroy();
4328 new_block->init(len);
4329 new_block->type=Query_cache_block::TABLE;
4330 new_block->used=used;
4331 new_block->n_tables=1;
4332 memmove((char*) new_block->data(), data, len-new_block->headers_len());
4333 relink(block, new_block, next, prev, pnext, pprev);
4334 if (tables_blocks == block)
4335 tables_blocks = new_block;
4336
4337 Query_cache_block_table *nlist_root = new_block->table(0);
4338 nlist_root->n = 0;
4339 nlist_root->next = tnext;
4340 tnext->prev = nlist_root;
4341 nlist_root->prev = tprev;
4342 tprev->next = nlist_root;
4343 DBUG_PRINT("qcache",
4344 ("list_root: %p tnext %p tprev %p tprev->next %p tnext->prev %p",
4345 list_root, tnext, tprev,
4346 tprev->next,tnext->prev));
4347 /*
4348 Go through all queries that uses this table and change them to
4349 point to the new table object
4350 */
4351 Query_cache_table *new_block_table=new_block->table();
4352 for (;tnext != nlist_root; tnext=tnext->next)
4353 tnext->parent= new_block_table;
4354 *border += len;
4355 *before = new_block;
4356 /* Fix pointer to table name */
4357 new_block->table()->table(new_block->table()->db() + tablename_offset);
4358 /* Fix hash to point at moved block */
4359 my_hash_replace(&tables, &record_idx, (uchar*) new_block);
4360
4361 DBUG_PRINT("qcache", ("moved %zu bytes to %p, new gap at %p",
4362 len, new_block, *border));
4363 break;
4364 }
4365 case Query_cache_block::QUERY:
4366 {
4367 HASH_SEARCH_STATE record_idx;
4368 DBUG_PRINT("qcache", ("block %p QUERY", block));
4369 if (*border == 0)
4370 break;
4371 BLOCK_LOCK_WR(block);
4372 size_t len = block->length, used = block->used;
4373 TABLE_COUNTER_TYPE n_tables = block->n_tables;
4374 Query_cache_block *prev = block->prev,
4375 *next = block->next,
4376 *pprev = block->pprev,
4377 *pnext = block->pnext,
4378 *new_block =(Query_cache_block*) *border;
4379 char *data = (char*) block->data();
4380 Query_cache_block *first_result_block = ((Query_cache_query *)
4381 block->data())->result();
4382 uchar *key;
4383 size_t key_length;
4384 key=query_cache_query_get_key((uchar*) block, &key_length, 0);
4385 my_hash_first(&queries, (uchar*) key, key_length, &record_idx);
4386 block->query()->unlock_n_destroy();
4387 block->destroy();
4388 // Move table of used tables
4389 memmove((char*) new_block->table(0), (char*) block->table(0),
4390 ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
4391 new_block->init(len);
4392 new_block->type=Query_cache_block::QUERY;
4393 new_block->used=used;
4394 new_block->n_tables=n_tables;
4395 memmove((char*) new_block->data(), data, len - new_block->headers_len());
4396 relink(block, new_block, next, prev, pnext, pprev);
4397 if (queries_blocks == block)
4398 queries_blocks = new_block;
4399 Query_cache_block_table *beg_of_table_table= block->table(0),
4400 *end_of_table_table= block->table(n_tables);
4401 uchar *beg_of_new_table_table= (uchar*) new_block->table(0);
4402
4403 for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++)
4404 {
4405 Query_cache_block_table *block_table = new_block->table(j);
4406
4407 // use aligment from beginning of table if 'next' is in same block
4408 if ((beg_of_table_table <= block_table->next) &&
4409 (block_table->next < end_of_table_table))
4410 ((Query_cache_block_table *)(beg_of_new_table_table +
4411 (((uchar*)block_table->next) -
4412 ((uchar*)beg_of_table_table))))->prev=
4413 block_table;
4414 else
4415 block_table->next->prev= block_table;
4416
4417 // use aligment from beginning of table if 'prev' is in same block
4418 if ((beg_of_table_table <= block_table->prev) &&
4419 (block_table->prev < end_of_table_table))
4420 ((Query_cache_block_table *)(beg_of_new_table_table +
4421 (((uchar*)block_table->prev) -
4422 ((uchar*)beg_of_table_table))))->next=
4423 block_table;
4424 else
4425 block_table->prev->next = block_table;
4426 }
4427 DBUG_PRINT("qcache", ("after circle tt"));
4428 *border += len;
4429 *before = new_block;
4430 new_block->query()->result(first_result_block);
4431 if (first_result_block != 0)
4432 {
4433 Query_cache_block *result_block = first_result_block;
4434 do
4435 {
4436 result_block->result()->parent(new_block);
4437 result_block = result_block->next;
4438 } while ( result_block != first_result_block );
4439 }
4440 Query_cache_query *new_query= ((Query_cache_query *) new_block->data());
4441 mysql_rwlock_init(key_rwlock_query_cache_query_lock, &new_query->lock);
4442
4443 /*
4444 If someone is writing to this block, inform the writer that the block
4445 has been moved.
4446 */
4447 Query_cache_tls *query_cache_tls= new_block->query()->writer();
4448 if (query_cache_tls != NULL)
4449 {
4450 query_cache_tls->first_query_block= new_block;
4451 }
4452 /* Fix hash to point at moved block */
4453 my_hash_replace(&queries, &record_idx, (uchar*) new_block);
4454 DBUG_PRINT("qcache", ("moved %zu bytes to %p, new gap at %p",
4455 len, new_block, *border));
4456 break;
4457 }
4458 case Query_cache_block::RES_INCOMPLETE:
4459 case Query_cache_block::RES_BEG:
4460 case Query_cache_block::RES_CONT:
4461 case Query_cache_block::RESULT:
4462 {
4463 DBUG_PRINT("qcache", ("block %p RES* (%d)", block,
4464 (int) block->type));
4465 if (*border == 0)
4466 break;
4467 Query_cache_block *query_block= block->result()->parent();
4468 BLOCK_LOCK_WR(query_block);
4469 Query_cache_block *next= block->next, *prev= block->prev;
4470 Query_cache_block::block_type type= block->type;
4471 size_t len = block->length, used = block->used;
4472 Query_cache_block *pprev = block->pprev,
4473 *pnext = block->pnext,
4474 *new_block =(Query_cache_block*) *border;
4475 char *data = (char*) block->data();
4476 block->destroy();
4477 new_block->init(len);
4478 new_block->type=type;
4479 new_block->used=used;
4480 memmove((char*) new_block->data(), data, len - new_block->headers_len());
4481 relink(block, new_block, next, prev, pnext, pprev);
4482 new_block->result()->parent(query_block);
4483 Query_cache_query *query = query_block->query();
4484 if (query->result() == block)
4485 query->result(new_block);
4486 *border += len;
4487 *before = new_block;
4488 /* If result writing complete && we have free space in block */
4489 size_t free_space= new_block->length - new_block->used;
4490 free_space-= free_space % ALIGN_SIZE(1);
4491 if (query->result()->type == Query_cache_block::RESULT &&
4492 new_block->length > new_block->used &&
4493 *gap + free_space > min_allocation_unit &&
4494 new_block->length - free_space > min_allocation_unit)
4495 {
4496 *border-= free_space;
4497 *gap+= free_space;
4498 DBUG_PRINT("qcache",
4499 ("rest of result free space added to gap (%zu)", *gap));
4500 new_block->length -= free_space;
4501 }
4502 BLOCK_UNLOCK_WR(query_block);
4503 DBUG_PRINT("qcache", ("moved %zu bytes to %p, new gap at %p",
4504 len, new_block, *border));
4505 break;
4506 }
4507 default:
4508 DBUG_PRINT("error", ("unexpected block type %d, block %p",
4509 (int)block->type, block));
4510 ok = 0;
4511 }
4512 DBUG_RETURN(ok);
4513}
4514
4515
4516void Query_cache::relink(Query_cache_block *oblock,
4517 Query_cache_block *nblock,
4518 Query_cache_block *next, Query_cache_block *prev,
4519 Query_cache_block *pnext, Query_cache_block *pprev)
4520{
4521 if (prev == oblock) //check pointer to himself
4522 {
4523 nblock->prev = nblock;
4524 nblock->next = nblock;
4525 }
4526 else
4527 {
4528 nblock->prev = prev;
4529 prev->next=nblock;
4530 }
4531 if (next != oblock)
4532 {
4533 nblock->next = next;
4534 next->prev=nblock;
4535 }
4536 nblock->pprev = pprev; // Physical pointer to himself have only 1 free block
4537 nblock->pnext = pnext;
4538 pprev->pnext=nblock;
4539 pnext->pprev=nblock;
4540}
4541
4542
4543my_bool Query_cache::join_results(size_t join_limit)
4544{
4545 my_bool has_moving = 0;
4546 DBUG_ENTER("Query_cache::join_results");
4547
4548 if (queries_blocks != 0)
4549 {
4550 DBUG_ASSERT(query_cache_size > 0);
4551 Query_cache_block *block = queries_blocks;
4552 do
4553 {
4554 Query_cache_query *header = block->query();
4555 if (header->result() != 0 &&
4556 header->result()->type == Query_cache_block::RESULT &&
4557 header->length() > join_limit)
4558 {
4559 Query_cache_block *new_result_block =
4560 get_free_block(ALIGN_SIZE(header->length()) +
4561 ALIGN_SIZE(sizeof(Query_cache_block)) +
4562 ALIGN_SIZE(sizeof(Query_cache_result)), 1, 0);
4563 if (new_result_block != 0)
4564 {
4565 has_moving = 1;
4566 Query_cache_block *first_result = header->result();
4567 size_t new_len = (header->length() +
4568 ALIGN_SIZE(sizeof(Query_cache_block)) +
4569 ALIGN_SIZE(sizeof(Query_cache_result)));
4570 if (new_result_block->length >
4571 ALIGN_SIZE(new_len) + min_allocation_unit)
4572 split_block(new_result_block, ALIGN_SIZE(new_len));
4573 BLOCK_LOCK_WR(block);
4574 header->result(new_result_block);
4575 new_result_block->type = Query_cache_block::RESULT;
4576 new_result_block->n_tables = 0;
4577 new_result_block->used = new_len;
4578
4579 new_result_block->next = new_result_block->prev = new_result_block;
4580 DBUG_PRINT("qcache", ("new block %zu/%zu (%zu)",
4581 new_result_block->length,
4582 new_result_block->used,
4583 header->length()));
4584
4585 Query_cache_result *new_result = new_result_block->result();
4586 new_result->parent(block);
4587 uchar *write_to = (uchar*) new_result->data();
4588 Query_cache_block *result_block = first_result;
4589 do
4590 {
4591 size_t len = (result_block->used - result_block->headers_len() -
4592 ALIGN_SIZE(sizeof(Query_cache_result)));
4593 DBUG_PRINT("loop", ("add block %zu/%zu (%zu)",
4594 result_block->length,
4595 result_block->used,
4596 len));
4597 memcpy((char *) write_to,
4598 (char*) result_block->result()->data(),
4599 len);
4600 write_to += len;
4601 Query_cache_block *old_result_block = result_block;
4602 result_block = result_block->next;
4603 free_memory_block(old_result_block);
4604 } while (result_block != first_result);
4605 BLOCK_UNLOCK_WR(block);
4606 }
4607 }
4608 block = block->next;
4609 } while ( block != queries_blocks );
4610 }
4611 DBUG_RETURN(has_moving);
4612}
4613
4614
4615uint Query_cache::filename_2_table_key (char *key, const char *path,
4616 uint32 *db_length)
4617{
4618 char tablename[FN_REFLEN+2], *filename, *dbname;
4619 DBUG_ENTER("Query_cache::filename_2_table_key");
4620
4621 /* Safety if filename didn't have a directory name */
4622 tablename[0]= FN_LIBCHAR;
4623 tablename[1]= FN_LIBCHAR;
4624 /* Convert filename to this OS's format in tablename */
4625 fn_format(tablename + 2, path, "", "", MY_REPLACE_EXT);
4626 filename= tablename + dirname_length(tablename + 2) + 2;
4627 /* Find start of databasename */
4628 for (dbname= filename - 2 ; dbname[-1] != FN_LIBCHAR ; dbname--) ;
4629 *db_length= (uint32)(filename - dbname) - 1;
4630 DBUG_PRINT("qcache", ("table '%-.*s.%s'", *db_length, dbname, filename));
4631
4632 DBUG_RETURN((uint) (strmake(strmake(key, dbname,
4633 MY_MIN(*db_length, NAME_LEN)) + 1,
4634 filename, NAME_LEN) - key) + 1);
4635}
4636
4637/****************************************************************************
4638 Functions to be used when debugging
4639****************************************************************************/
4640
4641#if defined(DBUG_OFF) && !defined(USE_QUERY_CACHE_INTEGRITY_CHECK)
4642
4643void wreck(uint line, const char *message) { query_cache_size = 0; }
4644void bins_dump() {}
4645void cache_dump() {}
4646void queries_dump() {}
4647void tables_dump() {}
4648my_bool check_integrity(bool not_locked) { return 0; }
4649my_bool in_list(Query_cache_block * root, Query_cache_block * point,
4650 const char *name) { return 0;}
4651my_bool in_blocks(Query_cache_block * point) { return 0; }
4652
4653#else
4654
4655
4656/*
4657 Debug method which switch query cache off but left content for
4658 investigation.
4659
4660 SYNOPSIS
4661 Query_cache::wreck()
4662 line line of the wreck() call
4663 message message for logging
4664*/
4665
4666void Query_cache::wreck(uint line, const char *message)
4667{
4668 THD *thd=current_thd;
4669 DBUG_ENTER("Query_cache::wreck");
4670 query_cache_size = 0;
4671 if (*message)
4672 DBUG_PRINT("error", (" %s", message));
4673 DBUG_PRINT("warning", ("=================================="));
4674 DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line));
4675 DBUG_PRINT("warning", ("=================================="));
4676 if (thd)
4677 thd->set_killed(KILL_CONNECTION);
4678 cache_dump();
4679 /* check_integrity(0); */ /* Can't call it here because of locks */
4680 bins_dump();
4681 DBUG_VOID_RETURN;
4682}
4683
4684
4685void Query_cache::bins_dump()
4686{
4687 uint i;
4688
4689 if (!initialized || query_cache_size == 0)
4690 {
4691 DBUG_PRINT("qcache", ("Query Cache not initialized"));
4692 return;
4693 }
4694
4695 DBUG_PRINT("qcache", ("mem_bin_num=%zu, mem_bin_steps=%zu",
4696 mem_bin_num, mem_bin_steps));
4697 DBUG_PRINT("qcache", ("-------------------------"));
4698 DBUG_PRINT("qcache", (" size idx step"));
4699 DBUG_PRINT("qcache", ("-------------------------"));
4700 for (i=0; i < mem_bin_steps; i++)
4701 {
4702 DBUG_PRINT("qcache", ("%10zu %3zd %10zu", steps[i].size, steps[i].idx,
4703 steps[i].increment));
4704 }
4705 DBUG_PRINT("qcache", ("-------------------------"));
4706 DBUG_PRINT("qcache", (" size num"));
4707 DBUG_PRINT("qcache", ("-------------------------"));
4708 for (i=0; i < mem_bin_num; i++)
4709 {
4710 DBUG_PRINT("qcache", ("%10zu %3d %p", bins[i].size, bins[i].number,
4711 &(bins[i])));
4712 if (bins[i].free_blocks)
4713 {
4714 Query_cache_block *block = bins[i].free_blocks;
4715 do{
4716 DBUG_PRINT("qcache", ("\\-- %zu %p %p %p %p %p",
4717 block->length,block,
4718 block->next,block->prev,
4719 block->pnext,block->pprev));
4720 block = block->next;
4721 } while ( block != bins[i].free_blocks );
4722 }
4723 }
4724 DBUG_PRINT("qcache", ("-------------------------"));
4725}
4726
4727
4728void Query_cache::cache_dump()
4729{
4730 if (!initialized || query_cache_size == 0)
4731 {
4732 DBUG_PRINT("qcache", ("Query Cache not initialized"));
4733 return;
4734 }
4735
4736 DBUG_PRINT("qcache", ("-------------------------------------"));
4737 DBUG_PRINT("qcache", (" length used t nt"));
4738 DBUG_PRINT("qcache", ("-------------------------------------"));
4739 Query_cache_block *i = first_block;
4740 do
4741 {
4742 DBUG_PRINT("qcache",
4743 ("%10zu %10zu %1d %2d %p %p %p %p %p",
4744 i->length, i->used, (int)i->type,
4745 i->n_tables,i,
4746 i->next,i->prev,i->pnext,
4747 i->pprev));
4748 i = i->pnext;
4749 } while ( i != first_block );
4750 DBUG_PRINT("qcache", ("-------------------------------------"));
4751}
4752
4753
4754void Query_cache::queries_dump()
4755{
4756
4757 if (!initialized)
4758 {
4759 DBUG_PRINT("qcache", ("Query Cache not initialized"));
4760 return;
4761 }
4762
4763 DBUG_PRINT("qcache", ("------------------"));
4764 DBUG_PRINT("qcache", (" QUERIES"));
4765 DBUG_PRINT("qcache", ("------------------"));
4766 if (queries_blocks != 0)
4767 {
4768 Query_cache_block *block = queries_blocks;
4769 do
4770 {
4771 size_t len;
4772 char *str = (char*) query_cache_query_get_key((uchar*) block, &len, 0);
4773 len-= QUERY_CACHE_FLAGS_SIZE; // Point at flags
4774 Query_cache_query_flags flags;
4775 memcpy(&flags, str+len, QUERY_CACHE_FLAGS_SIZE);
4776 str[len]= 0; // make zero ending DB name
4777 DBUG_PRINT("qcache", ("F: %u C: %u L: %llu T: '%s' (%zu) '%s' '%s'",
4778 flags.client_long_flag,
4779 flags.character_set_client_num,
4780 flags.limit,
4781 flags.time_zone->get_name()->ptr(),
4782 len, str, strend(str)+1));
4783 DBUG_PRINT("qcache", ("-b- %p %p %p %p %p", block,
4784 block->next, block->prev,
4785 block->pnext,block->pprev));
4786 memcpy(str + len, &flags, QUERY_CACHE_FLAGS_SIZE); // restore flags
4787 for (TABLE_COUNTER_TYPE t= 0; t < block->n_tables; t++)
4788 {
4789 Query_cache_table *table= block->table(t)->parent;
4790 DBUG_PRINT("qcache", ("-t- '%s' '%s'", table->db(), table->table()));
4791 }
4792 Query_cache_query *header = block->query();
4793 if (header->result())
4794 {
4795 Query_cache_block *result_block = header->result();
4796 Query_cache_block *result_beg = result_block;
4797 do
4798 {
4799 DBUG_PRINT("qcache", ("-r- %u %zu/%zu %p %p %p %p %p",
4800 (uint) result_block->type,
4801 result_block->length, result_block->used,
4802 result_block,
4803 result_block->next,
4804 result_block->prev,
4805 result_block->pnext,
4806 result_block->pprev));
4807 result_block = result_block->next;
4808 } while ( result_block != result_beg );
4809 }
4810 } while ((block=block->next) != queries_blocks);
4811 }
4812 else
4813 {
4814 DBUG_PRINT("qcache", ("no queries in list"));
4815 }
4816 DBUG_PRINT("qcache", ("------------------"));
4817}
4818
4819
4820void Query_cache::tables_dump()
4821{
4822 if (!initialized || query_cache_size == 0)
4823 {
4824 DBUG_PRINT("qcache", ("Query Cache not initialized"));
4825 return;
4826 }
4827
4828 DBUG_PRINT("qcache", ("--------------------"));
4829 DBUG_PRINT("qcache", ("TABLES"));
4830 DBUG_PRINT("qcache", ("--------------------"));
4831 if (tables_blocks != 0)
4832 {
4833 Query_cache_block *table_block = tables_blocks;
4834 do
4835 {
4836 Query_cache_table *table = table_block->table();
4837 DBUG_PRINT("qcache", ("'%s' '%s'", table->db(), table->table()));
4838 table_block = table_block->next;
4839 } while (table_block != tables_blocks);
4840 }
4841 else
4842 DBUG_PRINT("qcache", ("no tables in list"));
4843 DBUG_PRINT("qcache", ("--------------------"));
4844}
4845
4846
4847/**
4848 Checks integrity of the various linked lists
4849
4850 @return Error status code
4851 @retval FALSE Query cache is operational.
4852 @retval TRUE Query cache is broken.
4853*/
4854
4855my_bool Query_cache::check_integrity(bool locked)
4856{
4857 my_bool result = 0;
4858 uint i;
4859 DBUG_ENTER("check_integrity");
4860
4861 if (!locked)
4862 lock_and_suspend();
4863
4864 if (my_hash_check(&queries))
4865 {
4866 DBUG_PRINT("error", ("queries hash is damaged"));
4867 result = 1;
4868 }
4869
4870 if (my_hash_check(&tables))
4871 {
4872 DBUG_PRINT("error", ("tables hash is damaged"));
4873 result = 1;
4874 }
4875
4876 DBUG_PRINT("qcache", ("physical address check ..."));
4877 size_t free=0, used=0;
4878 Query_cache_block * block = first_block;
4879 do
4880 {
4881 /* When checking at system start, there is no block. */
4882 if (!block)
4883 break;
4884
4885 DBUG_PRINT("qcache", ("block %p, type %u...",
4886 block, (uint) block->type));
4887 // Check allignment
4888 if ((((size_t)block) % ALIGN_SIZE(1)) !=
4889 (((size_t)first_block) % ALIGN_SIZE(1)))
4890 {
4891 DBUG_PRINT("error",
4892 ("block %p do not aligned by %d", block,
4893 (int) ALIGN_SIZE(1)));
4894 result = 1;
4895 }
4896 // Check memory allocation
4897 if (block->pnext == first_block) // Is it last block?
4898 {
4899 if (((uchar*)block) + block->length !=
4900 ((uchar*)first_block) + query_cache_size)
4901 {
4902 DBUG_PRINT("error",
4903 ("block %p, type %u, ended at %p, but cache ended at %p",
4904 block, (uint) block->type,
4905 (((uchar*)block) + block->length),
4906 (((uchar*)first_block) + query_cache_size)));
4907 result = 1;
4908 }
4909 }
4910 else
4911 if (((uchar*)block) + block->length != ((uchar*)block->pnext))
4912 {
4913 DBUG_PRINT("error",
4914 ("block %p, type %u, ended at %p, but next block beginning at %p",
4915 block, (uint) block->type,
4916 (((uchar*)block) + block->length),
4917 ((uchar*)block->pnext)));
4918 }
4919 if (block->type == Query_cache_block::FREE)
4920 free+= block->length;
4921 else
4922 used+= block->length;
4923 switch(block->type) {
4924 case Query_cache_block::FREE:
4925 {
4926 Query_cache_memory_bin *bin = *((Query_cache_memory_bin **)
4927 block->data());
4928 //is it correct pointer?
4929 if (((uchar*)bin) < ((uchar*)bins) ||
4930 ((uchar*)bin) >= ((uchar*)first_block))
4931 {
4932 DBUG_PRINT("error",
4933 ("free block %p have bin pointer %p beyaond of bins array bounds [%p,%p]",
4934 block,
4935 bin,
4936 bins,
4937 first_block));
4938 result = 1;
4939 }
4940 else
4941 {
4942 size_t idx = (((uchar*)bin) - ((uchar*)bins)) /
4943 sizeof(Query_cache_memory_bin);
4944 if (in_list(bins[idx].free_blocks, block, "free memory"))
4945 result = 1;
4946 }
4947 break;
4948 }
4949 case Query_cache_block::TABLE:
4950 if (in_list(tables_blocks, block, "tables"))
4951 result = 1;
4952 if (in_table_list(block->table(0), block->table(0), "table list root"))
4953 result = 1;
4954 break;
4955 case Query_cache_block::QUERY:
4956 {
4957 if (in_list(queries_blocks, block, "query"))
4958 result = 1;
4959 for (TABLE_COUNTER_TYPE j=0; j < block->n_tables; j++)
4960 {
4961 Query_cache_block_table *block_table = block->table(j);
4962 Query_cache_block_table *block_table_root =
4963 (Query_cache_block_table *)
4964 (((uchar*)block_table->parent) -
4965 ALIGN_SIZE(sizeof(Query_cache_block_table)));
4966
4967 if (in_table_list(block_table, block_table_root, "table list"))
4968 result = 1;
4969 }
4970 break;
4971 }
4972 case Query_cache_block::RES_INCOMPLETE:
4973 // This type of block can be not lincked yet (in multithread environment)
4974 break;
4975 case Query_cache_block::RES_BEG:
4976 case Query_cache_block::RES_CONT:
4977 case Query_cache_block::RESULT:
4978 {
4979 Query_cache_block * query_block = block->result()->parent();
4980 if (((uchar*)query_block) < ((uchar*)first_block) ||
4981 ((uchar*)query_block) >= (((uchar*)first_block) + query_cache_size))
4982 {
4983 DBUG_PRINT("error",
4984 ("result block %p have query block pointer %p beyaond of block pool bounds [%p,%p]",
4985 block,
4986 query_block,
4987 first_block,
4988 (((uchar*)first_block) + query_cache_size)));
4989 result = 1;
4990 }
4991 else
4992 {
4993 BLOCK_LOCK_RD(query_block);
4994 if (in_list(queries_blocks, query_block, "query from results"))
4995 result = 1;
4996 if (in_list(query_block->query()->result(), block,
4997 "results"))
4998 result = 1;
4999 BLOCK_UNLOCK_RD(query_block);
5000 }
5001 break;
5002 }
5003 default:
5004 DBUG_PRINT("error", ("block %p have incorrect type %u",
5005 block, block->type));
5006 result = 1;
5007 }
5008
5009 block = block->pnext;
5010 } while (block != first_block);
5011
5012 if (used + free != query_cache_size)
5013 {
5014 DBUG_PRINT("error",
5015 ("used memory (%zu) + free memory (%zu) != query_cache_size (%zu)",
5016 used, free, query_cache_size));
5017 result = 1;
5018 }
5019
5020 if (free != free_memory)
5021 {
5022 DBUG_PRINT("error",
5023 ("free memory (%zu) != free_memory (%zu)",
5024 free, free_memory));
5025 result = 1;
5026 }
5027
5028 DBUG_PRINT("qcache", ("check queries ..."));
5029 if ((block = queries_blocks))
5030 {
5031 do
5032 {
5033 DBUG_PRINT("qcache", ("block %p, type %u...",
5034 block, (uint) block->type));
5035 size_t length;
5036 uchar *key = query_cache_query_get_key((uchar*) block, &length, 0);
5037 uchar* val = my_hash_search(&queries, key, length);
5038 if (((uchar*)block) != val)
5039 {
5040 DBUG_PRINT("error", ("block %p found in queries hash like %p",
5041 block, val));
5042 }
5043 if (in_blocks(block))
5044 result = 1;
5045 Query_cache_block * results = block->query()->result();
5046 if (results)
5047 {
5048 Query_cache_block * result_block = results;
5049 do
5050 {
5051 DBUG_PRINT("qcache", ("block %p, type %u...",
5052 block, (uint) block->type));
5053 if (in_blocks(result_block))
5054 result = 1;
5055
5056 result_block = result_block->next;
5057 } while (result_block != results);
5058 }
5059 block = block->next;
5060 } while (block != queries_blocks);
5061 }
5062
5063 DBUG_PRINT("qcache", ("check tables ..."));
5064 if ((block = tables_blocks))
5065 {
5066 do
5067 {
5068 DBUG_PRINT("qcache", ("block %p, type %u...",
5069 block, (uint) block->type));
5070 size_t length;
5071 uchar *key = query_cache_table_get_key((uchar*) block, &length, 0);
5072 uchar* val = my_hash_search(&tables, key, length);
5073 if (((uchar*)block) != val)
5074 {
5075 DBUG_PRINT("error", ("block %p found in tables hash like %p",
5076 block, val));
5077 }
5078
5079 if (in_blocks(block))
5080 result = 1;
5081 block=block->next;
5082 } while (block != tables_blocks);
5083 }
5084
5085 DBUG_PRINT("qcache", ("check free blocks"));
5086 for (i = 0; i < mem_bin_num; i++)
5087 {
5088 if ((block = bins[i].free_blocks))
5089 {
5090 uint count = 0;
5091 do
5092 {
5093 DBUG_PRINT("qcache", ("block %p, type %u...",
5094 block, (uint) block->type));
5095 if (in_blocks(block))
5096 result = 1;
5097
5098 count++;
5099 block=block->next;
5100 } while (block != bins[i].free_blocks);
5101 if (count != bins[i].number)
5102 {
5103 DBUG_PRINT("error", ("bins[%d].number= %d, but bin have %d blocks",
5104 i, bins[i].number, count));
5105 result = 1;
5106 }
5107 }
5108 }
5109 DBUG_ASSERT(result == 0);
5110 if (!locked)
5111 unlock();
5112 DBUG_RETURN(result);
5113}
5114
5115
5116my_bool Query_cache::in_blocks(Query_cache_block * point)
5117{
5118 my_bool result = 0;
5119 Query_cache_block *block = point;
5120 //back
5121 do
5122 {
5123 if (block->pprev->pnext != block)
5124 {
5125 DBUG_PRINT("error",
5126 ("block %p in physical list is incorrect linked, prev block %p refered as next to %p (check from %p)",
5127 block, block->pprev,
5128 block->pprev->pnext,
5129 point));
5130 //back trace
5131 for (; block != point; block = block->pnext)
5132 DBUG_PRINT("error", ("back trace %p", block));
5133 result = 1;
5134 goto err1;
5135 }
5136 block = block->pprev;
5137 } while (block != first_block && block != point);
5138 if (block != first_block)
5139 {
5140 DBUG_PRINT("error",
5141 ("block %p (%p<-->%p) not owned by pysical list",
5142 block, block->pprev, block->pnext));
5143 return 1;
5144 }
5145
5146err1:
5147 //forward
5148 block = point;
5149 do
5150 {
5151 if (block->pnext->pprev != block)
5152 {
5153 DBUG_PRINT("error",
5154 ("block %p in physicel list is incorrect linked, next block %p refered as prev to %p (check from %p)",
5155 block, block->pnext,
5156 block->pnext->pprev,
5157 point));
5158 //back trace
5159 for (; block != point; block = block->pprev)
5160 DBUG_PRINT("error", ("back trace %p", block));
5161 result = 1;
5162 goto err2;
5163 }
5164 block = block->pnext;
5165 } while (block != first_block);
5166err2:
5167 return result;
5168}
5169
5170
5171my_bool Query_cache::in_list(Query_cache_block * root,
5172 Query_cache_block * point,
5173 const char *name)
5174{
5175 my_bool result = 0;
5176 Query_cache_block *block = point;
5177 //back
5178 do
5179 {
5180 if (block->prev->next != block)
5181 {
5182 DBUG_PRINT("error",
5183 ("block %p in list '%s' %p is incorrect linked, prev block %p refered as next to %p (check from %p)",
5184 block, name, root, block->prev,
5185 block->prev->next,
5186 point));
5187 //back trace
5188 for (; block != point; block = block->next)
5189 DBUG_PRINT("error", ("back trace %p", block));
5190 result = 1;
5191 goto err1;
5192 }
5193 block = block->prev;
5194 } while (block != root && block != point);
5195 if (block != root)
5196 {
5197 DBUG_PRINT("error",
5198 ("block %p (%p<-->%p) not owned by list '%s' %p",
5199 block,
5200 block->prev, block->next,
5201 name, root));
5202 return 1;
5203 }
5204err1:
5205 // forward
5206 block = point;
5207 do
5208 {
5209 if (block->next->prev != block)
5210 {
5211 DBUG_PRINT("error",
5212 ("block %p in list '%s' %p is incorrect linked, next block %p refered as prev to %p (check from %p)",
5213 block, name, root, block->next,
5214 block->next->prev,
5215 point));
5216 //back trace
5217 for (; block != point; block = block->prev)
5218 DBUG_PRINT("error", ("back trace %p", block));
5219 result = 1;
5220 goto err2;
5221 }
5222 block = block->next;
5223 } while (block != root);
5224err2:
5225 return result;
5226}
5227
5228void dump_node(Query_cache_block_table * node,
5229 const char * call, const char * descr)
5230{
5231 DBUG_PRINT("qcache", ("%s: %s: node: %p", call, descr, node));
5232 DBUG_PRINT("qcache", ("%s: %s: node block: %p",
5233 call, descr, node->block()));
5234 DBUG_PRINT("qcache", ("%s: %s: next: %p", call, descr,
5235 node->next));
5236 DBUG_PRINT("qcache", ("%s: %s: prev: %p", call, descr,
5237 node->prev));
5238}
5239
5240my_bool Query_cache::in_table_list(Query_cache_block_table * root,
5241 Query_cache_block_table * point,
5242 const char *name)
5243{
5244 my_bool result = 0;
5245 Query_cache_block_table *table = point;
5246 dump_node(root, name, "parameter root");
5247 //back
5248 do
5249 {
5250 dump_node(table, name, "list element << ");
5251 if (table->prev->next != table)
5252 {
5253 DBUG_PRINT("error",
5254 ("table %p(%p) in list '%s' %p(%p) is incorrect linked, prev table %p(%p) refered as next to %p(%p) (check from %p(%p))",
5255 table, table->block(), name,
5256 root, root->block(),
5257 table->prev, table->prev->block(),
5258 table->prev->next,
5259 table->prev->next->block(),
5260 point, point->block()));
5261 //back trace
5262 for (; table != point; table = table->next)
5263 DBUG_PRINT("error", ("back trace %p(%p)",
5264 table, table->block()));
5265 result = 1;
5266 goto err1;
5267 }
5268 table = table->prev;
5269 } while (table != root && table != point);
5270 if (table != root)
5271 {
5272 DBUG_PRINT("error",
5273 ("table %p(%p) (%p(%p)<-->%p(%p)) not owned by list '%s' %p(%p)",
5274 table, table->block(),
5275 table->prev, table->prev->block(),
5276 table->next, table->next->block(),
5277 name, root, root->block()));
5278 return 1;
5279 }
5280err1:
5281 // forward
5282 table = point;
5283 do
5284 {
5285 dump_node(table, name, "list element >> ");
5286 if (table->next->prev != table)
5287 {
5288 DBUG_PRINT("error",
5289 ("table %p(%p) in list '%s' %p(%p) is incorrect linked, next table %p(%p) refered as prev to %p(%p) (check from %p(%p))",
5290 table, table->block(),
5291 name, root, root->block(),
5292 table->next, table->next->block(),
5293 table->next->prev,
5294 table->next->prev->block(),
5295 point, point->block()));
5296 //back trace
5297 for (; table != point; table = table->prev)
5298 DBUG_PRINT("error", ("back trace %p(%p)",
5299 table, table->block()));
5300 result = 1;
5301 goto err2;
5302 }
5303 table = table->next;
5304 } while (table != root);
5305err2:
5306 return result;
5307}
5308
5309#endif /* DBUG_OFF */
5310
5311#endif /*HAVE_QUERY_CACHE*/
5312
5313