MySQL  8.0.27
Source Code Documentation
table_cache.h
Go to the documentation of this file.
1 /* Copyright (c) 2012, 2021, Oracle and/or its affiliates.
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 <assert.h>
27 #include <stddef.h>
28 #include <sys/types.h>
29 #include <memory>
30 #include <string>
31 #include <unordered_map>
32 #include <utility>
33 
34 #include "lex_string.h"
35 #include "my_base.h"
36 
37 #include "my_psi_config.h"
40 #include "mysql/psi/mysql_mutex.h"
41 #include "sql/handler.h"
42 #include "sql/sql_base.h"
43 #include "sql/sql_class.h"
44 #include "sql/sql_plist.h"
45 #include "sql/system_variables.h"
46 #include "sql/table.h"
47 
49 
51 
52 /**
53  Cache for open TABLE objects.
54 
55  The idea behind this cache is that most statements don't need to
56  go to a central table definition cache to get a TABLE object and
57  therefore don't need to lock LOCK_open mutex.
58  Instead they only need to go to one Table_cache instance (the
59  specific instance is determined by thread id) and only lock the
60  mutex protecting this cache.
61  DDL statements that need to remove all TABLE objects from all caches
62  need to lock mutexes for all Table_cache instances, but they are rare.
63 
64  This significantly increases scalability in some scenarios.
65 */
66 
67 class Table_cache {
68  private:
69  /**
70  The table cache lock protects the following data:
71 
72  1) m_unused_tables list.
73  2) m_cache hash.
74  3) used_tables, free_tables lists in Table_cache_element objects in
75  this cache.
76  4) m_table_count - total number of TABLE objects in this cache.
77  5) the element in TABLE_SHARE::cache_element[] array that corresponds
78  to this cache,
79  6) in_use member in TABLE object.
80  7) Also ownership of mutexes for all caches are required to update
81  the refresh_version and table_def_shutdown_in_progress variables
82  and TABLE_SHARE::version member.
83 
84  The intention is that any query that finds a cached table object in
85  its designated table cache should only need to lock this mutex
86  instance and there should be no need to lock LOCK_open. LOCK_open is
87  still required however to create and release TABLE objects. However
88  most usage of the MySQL Server should be able to set the cache size
89  big enough so that the majority of the queries only need to lock this
90  mutex instance and not LOCK_open.
91  */
93 
94  /**
95  The hash of Table_cache_element objects, each table/table share that
96  has any TABLE object in the Table_cache has a Table_cache_element from
97  which the list of free TABLE objects in this table cache AND the list
98  of used TABLE objects in this table cache is stored.
99  We use Table_cache_element::share::table_cache_key as key for this hash.
100  */
101  std::unordered_map<std::string, std::unique_ptr<Table_cache_element>> m_cache;
102 
103  /**
104  List that contains all TABLE instances for tables in this particular
105  table cache that are in not use by any thread. Recently used TABLE
106  instances are appended to the end of the list. Thus the beginning of
107  the list contains which have been least recently used.
108  */
110 
111  /**
112  Total number of TABLE instances for tables in this particular table
113  cache (both in use by threads and not in use).
114  This value summed over all table caches is accessible to users as
115  Open_tables status variable.
116  */
118 
119 #ifdef HAVE_PSI_INTERFACE
122 #endif
123 
124  private:
125 #ifdef EXTRA_DEBUG
126  void check_unused();
127 #else
128  void check_unused() {}
129 #endif
130  inline void link_unused_table(TABLE *table);
131  inline void unlink_unused_table(TABLE *table);
132 
133  inline void free_unused_tables_if_necessary(THD *thd);
134 
135  public:
136  bool init();
137  void destroy();
138  static void init_psi_keys();
139 
140  /** Acquire lock on table cache instance. */
142  /** Release lock on table cache instance. */
144  /** Assert that caller owns lock on the table cache. */
146 
147  inline TABLE *get_table(THD *thd, const char *key, size_t key_length,
148  TABLE_SHARE **share);
149 
150  inline void release_table(THD *thd, TABLE *table);
151 
152  inline bool add_used_table(THD *thd, TABLE *table);
153  inline void remove_table(TABLE *table);
154 
155  /** Get number of TABLE instances in the cache. */
156  uint cached_tables() const { return m_table_count; }
157 
158  void free_all_unused_tables();
159 
160 #ifndef NDEBUG
161  void print_tables();
162 #endif
163 };
164 
165 /**
166  Container class for all table cache instances in the system.
167 */
168 
170  public:
171  /** Maximum supported number of table cache instances. */
172  static const int MAX_TABLE_CACHES = 64;
173 
174  /** Default number of table cache instances */
175  static const int DEFAULT_MAX_TABLE_CACHES = 16;
176 
177  bool init();
178  void destroy();
179 
180  /** Get instance of table cache to be used by particular connection. */
183  }
184 
185  /** Get index for the table cache in container. */
186  uint cache_index(Table_cache *cache) const {
187  return static_cast<uint>(cache - &m_table_cache[0]);
188  }
189 
191 
192  void lock_all_and_tdc();
193  void unlock_all_and_tdc();
194  void assert_owner(THD *thd);
195  void assert_owner_all();
197 
198  void free_table(THD *thd, enum_tdc_remove_table_type remove_type,
199  TABLE_SHARE *share);
200 
201  void free_all_unused_tables();
202 
203 #ifndef NDEBUG
204  void print_tables();
205 #endif
206 
207  friend class Table_cache_iterator;
208 
209  private:
210  /**
211  An array of Table_cache instances.
212  Only the first table_cache_instances elements in it are used.
213  */
215 };
216 
218 
219 /**
220  Element that represents the table in the specific table cache.
221  Plays for table cache instance role similar to role of TABLE_SHARE
222  for table definition cache.
223 
224  It is an implementation detail of Table_cache and is present
225  in the header file only to allow inlining of some methods.
226 */
227 
229  private:
230  /*
231  Doubly-linked (back-linked) lists of used and unused TABLE objects
232  for this table in this table cache (one such list per table cache).
233  */
234  typedef I_P_List<
237 
241 
242  public:
243  Table_cache_element(TABLE_SHARE *share_arg) : share(share_arg) {}
244 
245  TABLE_SHARE *get_share() const { return share; }
246 
247  friend class Table_cache;
248  friend class Table_cache_manager;
249  friend class Table_cache_iterator;
250 };
251 
252 /**
253  Iterator which allows to go through all used TABLE instances
254  for the table in all table caches.
255 */
256 
261 
262  inline void move_to_next_table();
263 
264  public:
265  /**
266  Construct iterator over all used TABLE objects for the table share.
267 
268  @note Assumes that caller owns locks on all table caches.
269  */
270  inline Table_cache_iterator(const TABLE_SHARE *share_arg);
271  inline TABLE *operator++(int);
272  inline void rewind();
273 };
274 
275 /**
276  Add table to the tail of unused tables list for table cache
277  (i.e. as the most recently used table in this list).
278 */
279 
281  if (m_unused_tables) {
282  table->next = m_unused_tables;
283  table->prev = m_unused_tables->prev;
284  m_unused_tables->prev = table;
285  table->prev->next = table;
286  } else
287  m_unused_tables = table->next = table->prev = table;
288  check_unused();
289 }
290 
291 /** Remove table from the unused tables list for table cache. */
292 
294  table->next->prev = table->prev;
295  table->prev->next = table->next;
296  if (table == m_unused_tables) {
298  if (table == m_unused_tables) m_unused_tables = nullptr;
299  }
300  check_unused();
301 }
302 
303 /**
304  Free unused TABLE instances if total number of TABLE objects
305  in table cache has exceeded table_cache_size_per_instance
306  limit.
307 
308  @note That we might need to free more than one instance during
309  this call if table_cache_size was changed dynamically.
310 */
311 
313  /*
314  We have too many TABLE instances around let us try to get rid of them.
315 
316  Note that we might need to free more than one TABLE object, and thus
317  need the below loop, in case when table_cache_size is changed dynamically,
318  at server run time.
319  */
323  TABLE *table_to_free = m_unused_tables;
324  remove_table(table_to_free);
325  intern_close_table(table_to_free);
327  }
329  }
330 }
331 
332 /**
333  Add newly created TABLE object which is going to be used right away
334  to the table cache.
335 
336  @note Caller should own lock on the table cache.
337 
338  @note Sets TABLE::in_use member as side effect.
339 
340  @retval false - success.
341  @retval true - failure.
342 */
343 
346 
347  assert_owner();
348 
349  assert(table->in_use == thd);
350 
351  /*
352  Try to get Table_cache_element representing this table in the cache
353  from array in the TABLE_SHARE.
354  */
355  el = table->s->cache_element[table_cache_manager.cache_index(this)];
356 
357  if (!el) {
358  /*
359  If TABLE_SHARE doesn't have pointer to the element representing table
360  in this cache, the element for the table must be absent from table the
361  cache.
362 
363  Allocate new Table_cache_element object and add it to the cache
364  and array in TABLE_SHARE.
365  */
366  std::string key(table->s->table_cache_key.str,
367  table->s->table_cache_key.length);
368  assert(m_cache.count(key) == 0);
369 
370  el = new Table_cache_element(table->s);
371  m_cache.emplace(key, std::unique_ptr<Table_cache_element>(el));
372  table->s->cache_element[table_cache_manager.cache_index(this)] = el;
373  }
374 
375  /* Add table to the used tables list */
376  el->used_tables.push_front(table);
377 
378  m_table_count++;
379 
381 
382  return false;
383 }
384 
385 /**
386  Prepare used or unused TABLE instance for destruction by removing
387  it from the table cache.
388 
389  @note Caller should own lock on the table cache.
390 */
391 
393  Table_cache_element *el =
395 
396  assert_owner();
397 
398  if (table->in_use) {
399  /* Remove from per-table chain of used TABLE objects. */
400  el->used_tables.remove(table);
401  } else {
402  /* Remove from per-table chain of unused TABLE objects. */
403  el->free_tables.remove(table);
404 
405  /* And per-cache unused chain. */
406  unlink_unused_table(table);
407  }
408 
409  m_table_count--;
410 
411  if (el->used_tables.is_empty() && el->free_tables.is_empty()) {
412  std::string key(table->s->table_cache_key.str,
413  table->s->table_cache_key.length);
414  m_cache.erase(key);
415  /*
416  Remove reference to deleted cache element from array
417  in the TABLE_SHARE.
418  */
419  table->s->cache_element[table_cache_manager.cache_index(this)] = nullptr;
420  }
421 }
422 
423 /**
424  Get an unused TABLE instance from the table cache.
425 
426  @param thd Thread context.
427  @param key Key identifying table.
428  @param key_length Length of key for the table.
429  @param[out] share NULL - if table cache doesn't contain any
430  information about the table (i.e. doesn't have
431  neither used nor unused TABLE objects for it).
432  Pointer to TABLE_SHARE for the table otherwise.
433 
434  @note Caller should own lock on the table cache.
435  @note Sets TABLE::in_use member as side effect.
436 
437  @retval non-NULL - pointer to unused TABLE object, "share" out-parameter
438  contains pointer to TABLE_SHARE for this table.
439  @retval NULL - no unused TABLE object was found, "share" parameter
440  contains pointer to TABLE_SHARE for this table if there
441  are used TABLE objects in cache and NULL otherwise.
442 */
443 
444 TABLE *Table_cache::get_table(THD *thd, const char *key, size_t key_length,
445  TABLE_SHARE **share) {
446  TABLE *table;
447 
448  assert_owner();
449 
450  *share = nullptr;
451 
452  std::string key_str(key, key_length);
453  const auto el_it = m_cache.find(key_str);
454  if (el_it == m_cache.end()) return nullptr;
455  Table_cache_element *el = el_it->second.get();
456 
457  *share = el->share;
458 
459  if ((table = el->free_tables.front())) {
460  assert(!table->in_use);
461 
462  /*
463  Unlink table from list of unused TABLE objects for this
464  table in this cache.
465  */
466  el->free_tables.remove(table);
467 
468  /* Unlink table from unused tables list for this cache. */
469  unlink_unused_table(table);
470 
471  /*
472  Add table to list of used TABLE objects for this table
473  in the table cache.
474  */
475  el->used_tables.push_front(table);
476 
477  table->in_use = thd;
478  /* The ex-unused table must be fully functional. */
479  assert(table->db_stat && table->file);
480  /* The children must be detached from the table. */
481  assert(!table->file->ha_extra(HA_EXTRA_IS_ATTACHED_CHILDREN));
482  }
483 
484  return table;
485 }
486 
487 /**
488  Put used TABLE instance back to the table cache and mark
489  it as unused.
490 
491  @note Caller should own lock on the table cache.
492  @note Sets TABLE::in_use member as side effect.
493 */
494 
496  Table_cache_element *el =
498 
499  assert_owner();
500 
501  assert(table->in_use);
502  assert(table->file);
503 
504  /* We shouldn't put the table to 'unused' list if the share is old. */
505  assert(!table->s->has_old_version());
506 
507  table->in_use = nullptr;
508 
509  /* Remove TABLE from the list of used objects for the table in this cache. */
510  el->used_tables.remove(table);
511  /* Add TABLE to the list of unused objects for the table in this cache. */
512  el->free_tables.push_front(table);
513  /* Also link it last in the list of unused TABLE objects for the cache. */
514  link_unused_table(table);
515 
516  /*
517  We free the least used tables, not the subject table, to keep the LRU order.
518  Note that in most common case the below call won't free anything.
519  */
521 }
522 
523 /**
524  Construct iterator over all used TABLE objects for the table share.
525 
526  @note Assumes that caller owns locks on all table caches.
527 */
529  : share(share_arg), current_cache_index(0), current_table(nullptr) {
532 }
533 
534 /** Helper that moves iterator to the next used TABLE for the table share. */
535 
539 
540  if ((el = share->cache_element[current_cache_index])) {
541  if ((current_table = el->used_tables.front())) break;
542  }
543  }
544 }
545 
546 /**
547  Get current used TABLE instance and move iterator to the next one.
548 
549  @note Assumes that caller owns locks on all table caches.
550 */
551 
554 
556 
557  if (current_table) {
560 
561  current_table = ++it;
562 
563  if (!current_table) {
566  }
567  }
568 
569  return result;
570 }
571 
574  current_table = nullptr;
576 }
577 
578 #endif /* TABLE_CACHE_INCLUDED */
Iterator for I_P_List.
Definition: sql_plist.h:167
Intrusive parameterized list.
Definition: sql_plist.h:74
void remove(T *a)
Definition: sql_plist.h:123
bool is_empty() const
Definition: sql_plist.h:89
void push_front(T *a)
Definition: sql_plist.h:90
T * front()
Definition: sql_plist.h:132
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:821
my_thread_id thread_id() const
Definition: sql_class.h:2253
struct System_status_var status_var
Definition: sql_class.h:1007
Element that represents the table in the specific table cache.
Definition: table_cache.h:228
Table_cache_element(TABLE_SHARE *share_arg)
Definition: table_cache.h:243
TABLE_list used_tables
Definition: table_cache.h:238
I_P_List< TABLE, I_P_List_adapter< TABLE, &TABLE::cache_next, &TABLE::cache_prev > > TABLE_list
Definition: table_cache.h:236
TABLE_list free_tables
Definition: table_cache.h:239
TABLE_SHARE * get_share() const
Definition: table_cache.h:245
TABLE_SHARE * share
Definition: table_cache.h:240
Iterator which allows to go through all used TABLE instances for the table in all table caches.
Definition: table_cache.h:257
const TABLE_SHARE * share
Definition: table_cache.h:258
Table_cache_iterator(const TABLE_SHARE *share_arg)
Construct iterator over all used TABLE objects for the table share.
Definition: table_cache.h:528
uint current_cache_index
Definition: table_cache.h:259
void move_to_next_table()
Helper that moves iterator to the next used TABLE for the table share.
Definition: table_cache.h:536
TABLE * current_table
Definition: table_cache.h:260
void rewind()
Definition: table_cache.h:572
TABLE * operator++(int)
Get current used TABLE instance and move iterator to the next one.
Definition: table_cache.h:552
Container class for all table cache instances in the system.
Definition: table_cache.h:169
Table_cache m_table_cache[MAX_TABLE_CACHES]
An array of Table_cache instances.
Definition: table_cache.h:214
uint cached_tables()
Get total number of used and unused TABLE objects in all table caches.
Definition: table_cache.cc:213
void unlock_all_and_tdc()
Release locks on all instances of table cache and table definition cache.
Definition: table_cache.cc:238
void print_tables()
Print debug information for the contents of all table cache instances.
Definition: table_cache.cc:348
void lock_all_and_tdc()
Acquire locks on all instances of table cache and table definition cache (i.e.
Definition: table_cache.cc:227
void assert_owner_all_and_tdc()
Assert that caller owns locks on all instances of table cache and table definition cache.
Definition: table_cache.cc:268
Table_cache * get_cache(THD *thd)
Get instance of table cache to be used by particular connection.
Definition: table_cache.h:181
bool init()
Initialize all instances of table cache to be used by server.
Definition: table_cache.cc:188
uint cache_index(Table_cache *cache) const
Get index for the table cache in container.
Definition: table_cache.h:186
void assert_owner_all()
Assert that caller owns locks on all instances of table cache.
Definition: table_cache.cc:258
void free_all_unused_tables()
Free all unused TABLE objects in all table cache instances.
Definition: table_cache.cc:336
static const int MAX_TABLE_CACHES
Maximum supported number of table cache instances.
Definition: table_cache.h:172
void free_table(THD *thd, enum_tdc_remove_table_type remove_type, TABLE_SHARE *share)
Remove and free all or some (depending on parameter) TABLE objects for the table from all table cache...
Definition: table_cache.cc:285
static const int DEFAULT_MAX_TABLE_CACHES
Default number of table cache instances.
Definition: table_cache.h:175
void assert_owner(THD *thd)
Assert that caller owns lock on the table cache.
Definition: table_cache.cc:249
void destroy()
Destroy all instances of table cache which were used by server.
Definition: table_cache.cc:202
Cache for open TABLE objects.
Definition: table_cache.h:67
TABLE * get_table(THD *thd, const char *key, size_t key_length, TABLE_SHARE **share)
Get an unused TABLE instance from the table cache.
Definition: table_cache.h:444
void lock()
Acquire lock on table cache instance.
Definition: table_cache.h:141
bool add_used_table(THD *thd, TABLE *table)
Add newly created TABLE object which is going to be used right away to the table cache.
Definition: table_cache.h:344
void unlock()
Release lock on table cache instance.
Definition: table_cache.h:143
bool init()
Initialize instance of table cache.
Definition: table_cache.cc:54
void release_table(THD *thd, TABLE *table)
Put used TABLE instance back to the table cache and mark it as unused.
Definition: table_cache.h:495
std::unordered_map< std::string, std::unique_ptr< Table_cache_element > > m_cache
The hash of Table_cache_element objects, each table/table share that has any TABLE object in the Tabl...
Definition: table_cache.h:101
void destroy()
Destroy instance of table cache.
Definition: table_cache.cc:63
mysql_mutex_t m_lock
The table cache lock protects the following data:
Definition: table_cache.h:92
uint m_table_count
Total number of TABLE instances for tables in this particular table cache (both in use by threads and...
Definition: table_cache.h:117
void assert_owner()
Assert that caller owns lock on the table cache.
Definition: table_cache.h:145
void free_all_unused_tables()
Free all unused TABLE objects in the table cache.
Definition: table_cache.cc:122
void check_unused()
Definition: table_cache.h:128
TABLE * m_unused_tables
List that contains all TABLE instances for tables in this particular table cache that are in not use ...
Definition: table_cache.h:109
void link_unused_table(TABLE *table)
Add table to the tail of unused tables list for table cache (i.e.
Definition: table_cache.h:280
static PSI_mutex_info m_mutex_keys[]
Definition: table_cache.h:121
static void init_psi_keys()
Init P_S instrumentation key for mutex protecting Table_cache instance.
Definition: table_cache.cc:67
void unlink_unused_table(TABLE *table)
Remove table from the unused tables list for table cache.
Definition: table_cache.h:293
uint cached_tables() const
Get number of TABLE instances in the cache.
Definition: table_cache.h:156
static PSI_mutex_key m_lock_key
Definition: table_cache.h:120
void print_tables()
Print debug information for the contents of the table cache.
Definition: table_cache.cc:137
void remove_table(TABLE *table)
Prepare used or unused TABLE instance for destruction by removing it from the table cache.
Definition: table_cache.h:392
void free_unused_tables_if_necessary(THD *thd)
Free unused TABLE instances if total number of TABLE objects in table cache has exceeded table_cache_...
Definition: table_cache.h:312
int ha_extra(enum ha_extra_function operation)
Request storage engine to do an extra operation: enable,disable or run some functionality.
Definition: handler.cc:8413
#define mysql_mutex_lock(M)
Definition: mysql_mutex.h:49
#define mysql_mutex_unlock(M)
Definition: mysql_mutex.h:56
Dialog Client Authentication nullptr
Definition: dialog.cc:352
mysql_mutex_t LOCK_open
LOCK_open protects the following variables/objects:
Definition: sql_base.cc:248
void intern_close_table(TABLE *table)
Definition: sql_base.cc:1099
unsigned int PSI_mutex_key
Instrumented mutex key.
Definition: psi_mutex_bits.h:51
#define mysql_mutex_assert_owner(M)
Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
Definition: mysql_mutex.h:111
static uint key_length
Definition: mi_test1.cc:42
This file includes constants used by all storage engines.
@ HA_EXTRA_IS_ATTACHED_CHILDREN
Definition: my_base.h:398
Defines various enable/disable and HAVE_ macros related to the performance schema instrumentation sys...
ABI for instrumented mutexes.
struct result result
Definition: result.h:33
Instrumentation helpers for mutexes.
Instrumentation helpers for mutexes.
required string key
Definition: replication_asynchronous_connection_failover.proto:59
enum_tdc_remove_table_type
Definition: sql_base.h:99
Hook class which via its methods specifies which members of T should be used for participating in a i...
Definition: sql_plist.h:197
const char * str
Definition: mysql_lex_string.h:40
size_t length
Definition: mysql_lex_string.h:41
Mutex information.
Definition: psi_mutex_bits.h:72
ulonglong table_open_cache_overflows
Definition: system_variables.h:468
This structure is shared between different table objects.
Definition: table.h:688
Table_cache_element ** cache_element
Array of table_cache_instances pointers to elements of table caches respresenting this table in each ...
Definition: table.h:739
LEX_CSTRING table_cache_key
Definition: table.h:769
bool has_old_version() const
Is this table share being expelled from the table definition cache?
Definition: table.h:1101
Definition: table.h:1394
THD * in_use
The current session using this table object.
Definition: table.h:1432
uint db_stat
Definition: table.h:1611
TABLE * next
Definition: table.h:1397
handler * file
Definition: table.h:1396
TABLE * prev
Definition: table.h:1397
TABLE_SHARE * s
Definition: table.h:1395
An instrumented mutex structure.
Definition: mysql_mutex_bits.h:49
Definition: result.h:29
ulong table_cache_instances
Definition: table_cache.h:50
Table_cache_manager table_cache_manager
Container for all table cache instances in the system.
Definition: table_cache.cc:39
ulong table_cache_size_per_instance
Definition: mysqld.cc:1307
unsigned int uint
Definition: uca-dump.cc:29