MySQL 8.1.0
Source Code Documentation
table_cache.h
Go to the documentation of this file.
1/* Copyright (c) 2012, 2023, 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"
41#include "sql/handler.h"
42#include "sql/sql_base.h"
43#include "sql/sql_class.h"
44#include "sql/sql_plist.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
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
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
190 uint cached_tables();
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
202
203#ifndef NDEBUG
204 void print_tables();
205#endif
206
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;
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;
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 const 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 */
377
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
394 table->s->cache_element[table_cache_manager.cache_index(this)];
395
396 assert_owner();
397
398 if (table->in_use) {
399 /* Remove from per-table chain of used TABLE objects. */
401 } else {
402 /* Remove from per-table chain of unused TABLE objects. */
404
405 /* And per-cache unused chain. */
407 }
408
410
411 if (el->used_tables.is_empty() && el->free_tables.is_empty()) {
412 const 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
444TABLE *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 const 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 */
467
468 /* Unlink table from unused tables list for this cache. */
470
471 /*
472 Add table to list of used TABLE objects for this table
473 in the table cache.
474 */
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
497 table->s->cache_element[table_cache_manager.cache_index(this)];
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. */
511 /* Add TABLE to the list of unused objects for the table in this cache. */
513 /* Also link it last in the list of unused TABLE objects for the cache. */
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
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
T * front()
Definition: sql_plist.h:132
void push_front(T *a)
Definition: sql_plist.h:90
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:33
my_thread_id thread_id() const
Definition: sql_class.h:2488
struct System_status_var status_var
Definition: sql_class.h:1118
Element that represents the table in the specific table cache.
Definition: table_cache.h:228
TABLE_SHARE * get_share() const
Definition: table_cache.h:245
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 * 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
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
Table_cache * get_cache(THD *thd)
Get instance of table cache to be used by particular connection.
Definition: table_cache.h:181
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
#define mysql_mutex_lock(M)
Definition: mysql_mutex.h:49
#define mysql_mutex_unlock(M)
Definition: mysql_mutex.h:56
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
mysql_mutex_t LOCK_open
LOCK_open protects the following variables/objects:
Definition: sql_base.cc:274
void intern_close_table(TABLE *table)
Definition: sql_base.cc:1137
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
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.
static PFS_engine_table_share_proxy table
Definition: pfs.cc:60
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
Mutex information.
Definition: psi_mutex_bits.h:72
ulonglong table_open_cache_overflows
Definition: system_variables.h:541
This structure is shared between different table objects.
Definition: table.h:691
Table_cache_element ** cache_element
Array of table_cache_instances pointers to elements of table caches respresenting this table in each ...
Definition: table.h:736
Definition: table.h:1394
TABLE * next
Definition: table.h:1397
TABLE * prev
Definition: table.h:1397
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:1339