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