1 /* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 #ifndef TABLE_CACHE_INCLUDED
24 #define TABLE_CACHE_INCLUDED
25
26 #include "my_global.h"
27 #include "sql_class.h"
28 #include "sql_base.h"
29
30 /**
31 Cache for open TABLE objects.
32
33 The idea behind this cache is that most statements don't need to
34 go to a central table definition cache to get a TABLE object and
35 therefore don't need to lock LOCK_open mutex.
36 Instead they only need to go to one Table_cache instance (the
37 specific instance is determined by thread id) and only lock the
38 mutex protecting this cache.
39 DDL statements that need to remove all TABLE objects from all caches
40 need to lock mutexes for all Table_cache instances, but they are rare.
41
42 This significantly increases scalability in some scenarios.
43 */
44
45 class Table_cache
46 {
47 private:
48 /**
49 The table cache lock protects the following data:
50
51 1) m_unused_tables list.
52 2) m_cache hash.
53 3) used_tables, free_tables lists in Table_cache_element objects in
54 this cache.
55 4) m_table_count - total number of TABLE objects in this cache.
56 5) the element in TABLE_SHARE::cache_element[] array that corresponds
57 to this cache,
58 6) in_use member in TABLE object.
59 7) Also ownership of mutexes for all caches are required to update
60 the refresh_version and table_def_shutdown_in_progress variables
61 and TABLE_SHARE::version member.
62
63 The intention is that any query that finds a cached table object in
64 its designated table cache should only need to lock this mutex
65 instance and there should be no need to lock LOCK_open. LOCK_open is
66 still required however to create and release TABLE objects. However
67 most usage of the MySQL Server should be able to set the cache size
68 big enough so that the majority of the queries only need to lock this
69 mutex instance and not LOCK_open.
70 */
71 mysql_mutex_t m_lock;
72
73 /**
74 The hash of Table_cache_element objects, each table/table share that
75 has any TABLE object in the Table_cache has a Table_cache_element from
76 which the list of free TABLE objects in this table cache AND the list
77 of used TABLE objects in this table cache is stored.
78 We use Table_cache_element::share::table_cache_key as key for this hash.
79 */
80 HASH m_cache;
81
82 /**
83 List that contains all TABLE instances for tables in this particular
84 table cache that are in not use by any thread. Recently used TABLE
85 instances are appended to the end of the list. Thus the beginning of
86 the list contains which have been least recently used.
87 */
88 TABLE *m_unused_tables;
89
90 /**
91 Total number of TABLE instances for tables in this particular table
92 cache (both in use by threads and not in use).
93 This value summed over all table caches is accessible to users as
94 Open_tables status variable.
95 */
96 uint m_table_count;
97
98 #ifdef HAVE_PSI_INTERFACE
99 static PSI_mutex_key m_lock_key;
100 static PSI_mutex_info m_mutex_keys[];
101 #endif
102
103 private:
104
105 #ifdef EXTRA_DEBUG
106 void check_unused();
107 #else
108 void check_unused() {}
109 #endif
110 inline void link_unused_table(TABLE *table);
111 inline void unlink_unused_table(TABLE *table);
112
113 inline void free_unused_tables_if_necessary(THD *thd);
114
115 public:
116
117 bool init();
118 void destroy();
119 static void init_psi_keys();
120
121 /** Acquire lock on table cache instance. */
lock()122 void lock() { mysql_mutex_lock(&m_lock); }
123 /** Release lock on table cache instance. */
unlock()124 void unlock() { mysql_mutex_unlock(&m_lock); }
125 /** Assert that caller owns lock on the table cache. */
assert_owner()126 void assert_owner() { mysql_mutex_assert_owner(&m_lock); }
127
128 inline TABLE* get_table(THD *thd, my_hash_value_type hash_value,
129 const char *key, uint key_length,
130 TABLE_SHARE **share);
131
132 inline void release_table(THD *thd, TABLE *table);
133
134 inline bool add_used_table(THD *thd, TABLE *table);
135 inline void remove_table(TABLE *table);
136
137 /** Get number of TABLE instances in the cache. */
cached_tables()138 uint cached_tables() const { return m_table_count; }
139
140 void free_all_unused_tables();
141
142 #ifndef DBUG_OFF
143 void print_tables();
144 #endif
145 };
146
147
148 /**
149 Container class for all table cache instances in the system.
150 */
151
152 class Table_cache_manager
153 {
154 public:
155
156 /** Maximum supported number of table cache instances. */
157 static const int MAX_TABLE_CACHES= 64;
158
159 bool init();
160 void destroy();
161
162 /** Get instance of table cache to be used by particular connection. */
get_cache(THD * thd)163 Table_cache* get_cache(THD *thd)
164 {
165 return &m_table_cache[thd->thread_id % table_cache_instances];
166 }
167
168 /** Get index for the table cache in container. */
cache_index(Table_cache * cache)169 uint cache_index(Table_cache *cache) const
170 {
171 return (cache - &m_table_cache[0]);
172 }
173
174 uint cached_tables();
175
176 void lock_all_and_tdc();
177 void unlock_all_and_tdc();
178 void assert_owner_all();
179 void assert_owner_all_and_tdc();
180
181 void free_table(THD *thd,
182 enum_tdc_remove_table_type remove_type,
183 TABLE_SHARE *share);
184
185 void free_all_unused_tables();
186
187 #ifndef DBUG_OFF
188 void print_tables();
189 #endif
190
191 friend class Table_cache_iterator;
192
193 private:
194
195 /**
196 An array of Table_cache instances.
197 Only the first table_cache_instances elements in it are used.
198 */
199 Table_cache m_table_cache[MAX_TABLE_CACHES];
200 };
201
202
203 extern Table_cache_manager table_cache_manager;
204
205
206 /**
207 Element that represents the table in the specific table cache.
208 Plays for table cache instance role similar to role of TABLE_SHARE
209 for table definition cache.
210
211 It is an implementation detail of Table_cache and is present
212 in the header file only to allow inlining of some methods.
213 */
214
215 class Table_cache_element
216 {
217 private:
218 /*
219 Doubly-linked (back-linked) lists of used and unused TABLE objects
220 for this table in this table cache (one such list per table cache).
221 */
222 typedef I_P_List <TABLE,
223 I_P_List_adapter<TABLE,
224 &TABLE::cache_next,
225 &TABLE::cache_prev> > TABLE_list;
226
227 TABLE_list used_tables;
228 TABLE_list free_tables;
229 TABLE_SHARE *share;
230
231 public:
232
Table_cache_element(TABLE_SHARE * share_arg)233 Table_cache_element(TABLE_SHARE *share_arg)
234 : share(share_arg)
235 {
236 }
237
get_share()238 TABLE_SHARE * get_share() const { return share; };
239
240 friend class Table_cache;
241 friend class Table_cache_manager;
242 friend class Table_cache_iterator;
243 };
244
245
246 /**
247 Iterator which allows to go through all used TABLE instances
248 for the table in all table caches.
249 */
250
251 class Table_cache_iterator
252 {
253 const TABLE_SHARE *share;
254 uint current_cache_index;
255 TABLE *current_table;
256
257 inline void move_to_next_table();
258
259 public:
260 /**
261 Construct iterator over all used TABLE objects for the table share.
262
263 @note Assumes that caller owns locks on all table caches.
264 */
265 inline Table_cache_iterator(const TABLE_SHARE *share_arg);
266 inline TABLE* operator++(int);
267 inline void rewind();
268 };
269
270
271 /**
272 Add table to the tail of unused tables list for table cache
273 (i.e. as the most recently used table in this list).
274 */
275
link_unused_table(TABLE * table)276 void Table_cache::link_unused_table(TABLE *table)
277 {
278 if (m_unused_tables)
279 {
280 table->next= m_unused_tables;
281 table->prev= m_unused_tables->prev;
282 m_unused_tables->prev= table;
283 table->prev->next= table;
284 }
285 else
286 m_unused_tables= table->next= table->prev= table;
287 check_unused();
288 }
289
290
291 /** Remove table from the unused tables list for table cache. */
292
unlink_unused_table(TABLE * table)293 void Table_cache::unlink_unused_table(TABLE *table)
294 {
295 table->next->prev= table->prev;
296 table->prev->next= table->next;
297 if (table == m_unused_tables)
298 {
299 m_unused_tables= m_unused_tables->next;
300 if (table == m_unused_tables)
301 m_unused_tables= NULL;
302 }
303 check_unused();
304 }
305
306
307 /**
308 Free unused TABLE instances if total number of TABLE objects
309 in table cache has exceeded table_cache_size_per_instance
310 limit.
311
312 @note That we might need to free more than one instance during
313 this call if table_cache_size was changed dynamically.
314 */
315
free_unused_tables_if_necessary(THD * thd)316 void Table_cache::free_unused_tables_if_necessary(THD *thd)
317 {
318 /*
319 We have too many TABLE instances around let us try to get rid of them.
320
321 Note that we might need to free more than one TABLE object, and thus
322 need the below loop, in case when table_cache_size is changed dynamically,
323 at server run time.
324 */
325 if (m_table_count > table_cache_size_per_instance && m_unused_tables)
326 {
327 mysql_mutex_lock(&LOCK_open);
328 while (m_table_count > table_cache_size_per_instance &&
329 m_unused_tables)
330 {
331 TABLE *table_to_free= m_unused_tables;
332 remove_table(table_to_free);
333 intern_close_table(table_to_free);
334 thd->status_var.table_open_cache_overflows++;
335 }
336 mysql_mutex_unlock(&LOCK_open);
337 }
338 }
339
340
341 /**
342 Add newly created TABLE object which is going to be used right away
343 to the table cache.
344
345 @note Caller should own lock on the table cache.
346
347 @note Sets TABLE::in_use member as side effect.
348
349 @retval false - success.
350 @retval true - failure.
351 */
352
add_used_table(THD * thd,TABLE * table)353 bool Table_cache::add_used_table(THD *thd, TABLE *table)
354 {
355 Table_cache_element *el;
356
357 assert_owner();
358
359 DBUG_ASSERT(table->in_use == thd);
360
361 /*
362 Try to get Table_cache_element representing this table in the cache
363 from array in the TABLE_SHARE.
364 */
365 el= table->s->cache_element[table_cache_manager.cache_index(this)];
366
367 if (!el)
368 {
369 /*
370 If TABLE_SHARE doesn't have pointer to the element representing table
371 in this cache, the element for the table must be absent from table the
372 cache.
373
374 Allocate new Table_cache_element object and add it to the cache
375 and array in TABLE_SHARE.
376 */
377 DBUG_ASSERT(! my_hash_search(&m_cache,
378 (uchar*)table->s->table_cache_key.str,
379 table->s->table_cache_key.length));
380
381 if (!(el= new Table_cache_element(table->s)))
382 return true;
383
384 if (my_hash_insert(&m_cache, (uchar*)el))
385 {
386 delete el;
387 return true;
388 }
389
390 table->s->cache_element[table_cache_manager.cache_index(this)]= el;
391 }
392
393 /* Add table to the used tables list */
394 el->used_tables.push_front(table);
395
396 m_table_count++;
397
398 free_unused_tables_if_necessary(thd);
399
400 return false;
401 }
402
403
404 /**
405 Prepare used or unused TABLE instance for destruction by removing
406 it from the table cache.
407
408 @note Caller should own lock on the table cache.
409 */
410
remove_table(TABLE * table)411 void Table_cache::remove_table(TABLE *table)
412 {
413 Table_cache_element *el=
414 table->s->cache_element[table_cache_manager.cache_index(this)];
415
416 assert_owner();
417
418 if (table->in_use)
419 {
420 /* Remove from per-table chain of used TABLE objects. */
421 el->used_tables.remove(table);
422 }
423 else
424 {
425 /* Remove from per-table chain of unused TABLE objects. */
426 el->free_tables.remove(table);
427
428 /* And per-cache unused chain. */
429 unlink_unused_table(table);
430 }
431
432 m_table_count--;
433
434 if (el->used_tables.is_empty() && el->free_tables.is_empty())
435 {
436 (void) my_hash_delete(&m_cache, (uchar*) el);
437 /*
438 Remove reference to deleted cache element from array
439 in the TABLE_SHARE.
440 */
441 table->s->cache_element[table_cache_manager.cache_index(this)]= NULL;
442 }
443 }
444
445
446 /**
447 Get an unused TABLE instance from the table cache.
448
449 @param thd Thread context.
450 @param hash_value Hash value for the key identifying table.
451 @param key Key identifying table.
452 @param key_length Length of key for the table.
453 @param[out] share NULL - if table cache doesn't contain any
454 information about the table (i.e. doesn't have
455 neither used nor unused TABLE objects for it).
456 Pointer to TABLE_SHARE for the table otherwise.
457
458 @note Caller should own lock on the table cache.
459 @note Sets TABLE::in_use member as side effect.
460
461 @retval non-NULL - pointer to unused TABLE object, "share" out-parameter
462 contains pointer to TABLE_SHARE for this table.
463 @retval NULL - no unused TABLE object was found, "share" parameter
464 contains pointer to TABLE_SHARE for this table if there
465 are used TABLE objects in cache and NULL otherwise.
466 */
467
get_table(THD * thd,my_hash_value_type hash_value,const char * key,uint key_length,TABLE_SHARE ** share)468 TABLE* Table_cache::get_table(THD *thd, my_hash_value_type hash_value,
469 const char *key, uint key_length,
470 TABLE_SHARE **share)
471 {
472 Table_cache_element *el;
473 TABLE *table;
474
475 assert_owner();
476
477 *share= NULL;
478
479 if (!(el= (Table_cache_element*) my_hash_search_using_hash_value(&m_cache,
480 hash_value, (uchar*) key, key_length)))
481 return NULL;
482
483 *share= el->share;
484
485 if ((table= el->free_tables.front()))
486 {
487 DBUG_ASSERT(!table->in_use);
488
489 /*
490 Unlink table from list of unused TABLE objects for this
491 table in this cache.
492 */
493 el->free_tables.remove(table);
494
495 /* Unlink table from unused tables list for this cache. */
496 unlink_unused_table(table);
497
498 /*
499 Add table to list of used TABLE objects for this table
500 in the table cache.
501 */
502 el->used_tables.push_front(table);
503
504 table->in_use= thd;
505 /* The ex-unused table must be fully functional. */
506 DBUG_ASSERT(table->db_stat && table->file);
507 /* The children must be detached from the table. */
508 DBUG_ASSERT(! table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN));
509 }
510
511 return table;
512 }
513
514
515 /**
516 Put used TABLE instance back to the table cache and mark
517 it as unused.
518
519 @note Caller should own lock on the table cache.
520 @note Sets TABLE::in_use member as side effect.
521 */
522
release_table(THD * thd,TABLE * table)523 void Table_cache::release_table(THD *thd, TABLE *table)
524 {
525 Table_cache_element *el=
526 table->s->cache_element[table_cache_manager.cache_index(this)];
527
528 assert_owner();
529
530 DBUG_ASSERT(table->in_use);
531 DBUG_ASSERT(table->file);
532
533 /* We shouldn't put the table to 'unused' list if the share is old. */
534 DBUG_ASSERT(! table->s->has_old_version());
535
536 table->in_use= NULL;
537
538 /* Remove TABLE from the list of used objects for the table in this cache. */
539 el->used_tables.remove(table);
540 /* Add TABLE to the list of unused objects for the table in this cache. */
541 el->free_tables.push_front(table);
542 /* Also link it last in the list of unused TABLE objects for the cache. */
543 link_unused_table(table);
544
545 /*
546 We free the least used tables, not the subject table, to keep the LRU order.
547 Note that in most common case the below call won't free anything.
548 */
549 free_unused_tables_if_necessary(thd);
550 }
551
552
553 /**
554 Construct iterator over all used TABLE objects for the table share.
555
556 @note Assumes that caller owns locks on all table caches.
557 */
Table_cache_iterator(const TABLE_SHARE * share_arg)558 Table_cache_iterator::Table_cache_iterator(const TABLE_SHARE *share_arg)
559 : share(share_arg), current_cache_index(0), current_table(NULL)
560 {
561 table_cache_manager.assert_owner_all();
562 move_to_next_table();
563 }
564
565
566 /** Helper that moves iterator to the next used TABLE for the table share. */
567
move_to_next_table()568 void Table_cache_iterator::move_to_next_table()
569 {
570 for (; current_cache_index < table_cache_instances; ++current_cache_index)
571 {
572 Table_cache_element *el;
573
574 if ((el= share->cache_element[current_cache_index]))
575 {
576 if ((current_table= el->used_tables.front()))
577 break;
578 }
579 }
580 }
581
582
583 /**
584 Get current used TABLE instance and move iterator to the next one.
585
586 @note Assumes that caller owns locks on all table caches.
587 */
588
589 TABLE* Table_cache_iterator::operator ++(int)
590 {
591 table_cache_manager.assert_owner_all();
592
593 TABLE *result= current_table;
594
595 if (current_table)
596 {
597 Table_cache_element::TABLE_list::Iterator
598 it(share->cache_element[current_cache_index]->used_tables, current_table);
599
600 current_table= ++it;
601
602 if (!current_table)
603 {
604 ++current_cache_index;
605 move_to_next_table();
606 }
607 }
608
609 return result;
610 }
611
612
rewind()613 void Table_cache_iterator::rewind()
614 {
615 current_cache_index= 0;
616 current_table= NULL;
617 move_to_next_table();
618 }
619
620 #endif /* TABLE_CACHE_INCLUDED */
621