1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
|
/* Copyright (c) 2015, 2025, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef DD_CACHE__SHARED_DICTIONARY_CACHE_INCLUDED
#define DD_CACHE__SHARED_DICTIONARY_CACHE_INCLUDED
#include <stdio.h>
#include "sql/dd/impl/cache/shared_multi_map.h" // Shared_multi_map
#include "sql/dd/types/abstract_table.h"
#include "sql/dd/types/charset.h" // Charset
#include "sql/dd/types/collation.h" // Collation
#include "sql/dd/types/column_statistics.h" // Column_statistics
#include "sql/dd/types/event.h" // Event
#include "sql/dd/types/routine.h" // Routine
#include "sql/dd/types/schema.h" // Schema
#include "sql/dd/types/spatial_reference_system.h" // Spatial_reference_system
#include "sql/dd/types/table.h" // IWYU pragma: keep
#include "sql/dd/types/tablespace.h" // Tablespace
#include "sql/handler.h" // enum_tx_isolation
class THD;
namespace dd {
namespace cache {
/**
Shared dictionary cache containing several maps.
The dictionary cache is mainly a collection of shared maps for the
object types supported. The functions dispatch to the appropriate
map based on the key and object type parameter. Cache misses are handled
by retrieving the object from the storage adapter singleton.
The shared dictionary cache itself does not handle concurrency at this
outer layer. Concurrency is handled by the various instances of the
shared multi map.
*/
template <typename T>
class Cache_element;
class Shared_dictionary_cache {
private:
// Collation and character set cache sizes are chosen so that they can hold
// all collations and character sets built into the server. The spatial
// reference system cache size is chosen to hold a reasonable number of SRSs
// for normal server use.
static const size_t collation_capacity = 256;
static const size_t column_statistics_capacity = 32;
static const size_t charset_capacity = 64;
static const size_t event_capacity = 256;
static const size_t spatial_reference_system_capacity = 256;
/**
Maximum number of DD resource group objects to be kept in
cache. We use value of 32 which is a fairly reasonable upper limit
of resource group configurations that may be in use.
*/
static const size_t resource_group_capacity = 32;
Shared_multi_map<Abstract_table> m_abstract_table_map;
Shared_multi_map<Charset> m_charset_map;
Shared_multi_map<Collation> m_collation_map;
Shared_multi_map<Column_statistics> m_column_stat_map;
Shared_multi_map<Event> m_event_map;
Shared_multi_map<Resource_group> m_resource_group_map;
Shared_multi_map<Routine> m_routine_map;
Shared_multi_map<Schema> m_schema_map;
Shared_multi_map<Spatial_reference_system> m_spatial_reference_system_map;
Shared_multi_map<Tablespace> m_tablespace_map;
template <typename T>
struct Type_selector {}; // Dummy type to use for
// selecting map instance.
/**
Overloaded functions to use for selecting map instance based
on a key type. Const and non-const variants.
*/
Shared_multi_map<Abstract_table> *m_map(Type_selector<Abstract_table>) {
return &m_abstract_table_map;
}
Shared_multi_map<Charset> *m_map(Type_selector<Charset>) {
return &m_charset_map;
}
Shared_multi_map<Collation> *m_map(Type_selector<Collation>) {
return &m_collation_map;
}
Shared_multi_map<Column_statistics> *m_map(Type_selector<Column_statistics>) {
return &m_column_stat_map;
}
Shared_multi_map<Event> *m_map(Type_selector<Event>) { return &m_event_map; }
Shared_multi_map<Resource_group> *m_map(Type_selector<Resource_group>) {
return &m_resource_group_map;
}
Shared_multi_map<Routine> *m_map(Type_selector<Routine>) {
return &m_routine_map;
}
Shared_multi_map<Schema> *m_map(Type_selector<Schema>) {
return &m_schema_map;
}
Shared_multi_map<Spatial_reference_system> *m_map(
Type_selector<Spatial_reference_system>) {
return &m_spatial_reference_system_map;
}
Shared_multi_map<Tablespace> *m_map(Type_selector<Tablespace>) {
return &m_tablespace_map;
}
const Shared_multi_map<Abstract_table> *m_map(
Type_selector<Abstract_table>) const {
return &m_abstract_table_map;
}
const Shared_multi_map<Charset> *m_map(Type_selector<Charset>) const {
return &m_charset_map;
}
const Shared_multi_map<Collation> *m_map(Type_selector<Collation>) const {
return &m_collation_map;
}
const Shared_multi_map<Column_statistics> *m_map(
Type_selector<Column_statistics>) const {
return &m_column_stat_map;
}
const Shared_multi_map<Schema> *m_map(Type_selector<Schema>) const {
return &m_schema_map;
}
const Shared_multi_map<Spatial_reference_system> *m_map(
Type_selector<Spatial_reference_system>) const {
return &m_spatial_reference_system_map;
}
const Shared_multi_map<Tablespace> *m_map(Type_selector<Tablespace>) const {
return &m_tablespace_map;
}
const Shared_multi_map<Resource_group> *m_map(
Type_selector<Resource_group>) const {
return &m_resource_group_map;
}
/**
Template function to get a map instance.
To support generic code, the map instances are available through
template function instances. This allows looking up the
appropriate instance based on the key type. We must use
overloading to accomplish this (see above). Const and non-const
variants.
@tparam T Dictionary object type.
@return The shared map handling objects of type T.
*/
template <typename T>
Shared_multi_map<T> *m_map() {
return m_map(Type_selector<T>());
}
template <typename T>
const Shared_multi_map<T> *m_map() const {
return m_map(Type_selector<T>());
}
Shared_dictionary_cache() = default;
public:
static Shared_dictionary_cache *instance();
// Set capacity of the shared maps.
static void init();
// Shutdown the shared maps.
static void shutdown();
// Reset the shared cache. Optionally keep the core DD table meta data.
static void reset(bool keep_dd_entities);
// Reset the table and tablespace partitions.
static bool reset_tables_and_tablespaces(THD *thd);
/**
Check if an element with the given key is available.
@param key Key to check for presence.
@retval true The key exist.
@retval false The key does not exist.
*/
template <typename K, typename T>
bool available(const K &key) {
return m_map<T>()->available(key);
}
/**
Get an element from the cache, given the key.
The operation retrieves an element by one of its keys from the cache
(possibly involving a cache miss, which will need the thd to handle the
miss) and returns it through the parameter. If there is no element for
the given key, NULL is returned. The cache owns the returned element,
i.e., the caller must not delete it. After using the element, release()
must be called for every element received via get(). The reference
counter for the element is incremented if the element is retrieved from
the shared cache.
@tparam K Key type.
@tparam T Dictionary object type.
@param thd Thread context.
@param key Key to use for looking up the object.
@param [out] element Element pointer, if present. NULL if not present.
@retval false No error.
@retval true Error (from handling a cache miss).
*/
template <typename K, typename T>
bool get(THD *thd, const K &key, Cache_element<T> **element);
MY_COMPILER_DIAGNOSTIC_PUSH()
MY_COMPILER_CLANG_WORKAROUND_TPARAM_DOCBUG()
/**
Read an object directly from disk, given the key.
The operation retrieves an object by one of its keys from the persistent
dd tables. The object is returned without being added to the shared
cache. The object returned is owned by the caller, who thus becomes
responsible of deleting it.
@tparam K Key type.
@tparam T Dictionary object type.
@param thd Thread context.
@param key Key to use for looking up the object.
@param isolation Isolation level to use.
@param [out] object Object pointer, if present. NULL if not present.
@retval false No error.
@retval true Error (from reading from the DD tables).
*/
MY_COMPILER_DIAGNOSTIC_POP()
template <typename K, typename T>
bool get_uncached(THD *thd, const K &key, enum_tx_isolation isolation,
const T **object) const;
/**
Add an object to the shared cache.
The object may not be present already. The object is added to the cache,
the use counter of its element wrapper in incremented, and the element
pointer is returned. The user must release the object afterwards. The
cache is the owner of the returned element and object.
@tparam T Dictionary object type.
@param object Object pointer to be added. May not be NULL.
@param element Element pointer, if present. NULL if not present.
*/
template <typename T>
void put(const T *object, Cache_element<T> **element);
/**
Release an element used by a client.
The element must be present and in use. If the element becomes unused,
it is added to the free list, which is then rectified to enforce
its capacity constraints.
@tparam T Dictionary object type.
@param e Element pointer.
*/
template <typename T>
void release(Cache_element<T> *e) {
m_map<T>()->release(e);
}
/**
Delete an element from the cache.
This function will remove the element from the cache and delete the
object pointed to. This means that all keys associated with the element
will be removed from the maps, and the cache element wrapper will be
deleted. The object may not be accessed after calling this function.
@tparam T Dictionary object type.
@param element Element pointer.
*/
template <typename T>
void drop(Cache_element<T> *element) {
m_map<T>()->drop(element);
}
/**
Delete an element corresponding to the key from the cache if exists.
This function will find the element corresponding to the key if
it exists. After that it will remove the element from the cache
i.e. all maps, and delete the object pointed to. This means that
all keys associated with the element will be removed from the maps,
and the cache element wrapper will be deleted.
@tparam K Key type.
@tparam T Dictionary object type.
@param key Key to be checked.
*/
template <typename K, typename T>
void drop_if_present(const K &key) {
m_map<T>()->drop_if_present(key);
}
/**
Replace the object and re-create the keys for an element.
The operation removes the current keys from the internal maps in the
cache, assigns the new object to the element, generates new keys based
on the new object, and inserts the new keys into the internal maps in the
cache. The old object is deleted.
@tparam T Dictionary object type.
@param element Element pointer.
@param object New object to replace the old one.
*/
template <typename T>
void replace(Cache_element<T> *element, const T *object) {
m_map<T>()->replace(element, object);
}
/**
Debug dump of a shared cache partition to stderr.
@tparam T Dictionary object type.
*/
template <typename T>
void dump() const {
#ifndef NDEBUG
fprintf(stderr, "================================\n");
fprintf(stderr, "Shared dictionary cache\n");
m_map<T>()->dump();
fprintf(stderr, "================================\n");
#endif
}
};
} // namespace cache
} // namespace dd
#endif // DD_CACHE__SHARED_DICTIONARY_CACHE_INCLUDED
|