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