1 /*****************************************************************************
2
3 Copyright (c) 1996, 2020, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2012, Facebook Inc.
5
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License, version 2.0, as published by the
8 Free Software Foundation.
9
10 This program is also distributed with certain software (including but not
11 limited to OpenSSL) that is licensed under separate terms, as designated in a
12 particular file or component or in included license documentation. The authors
13 of MySQL hereby grant you an additional permission to link the program and
14 your derivative works with the separately licensed software that they have
15 included with MySQL.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20 for more details.
21
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26 *****************************************************************************/
27
28 /** @file include/dict0mem.h
29 Data dictionary memory object creation
30
31 Created 1/8/1996 Heikki Tuuri
32 *******************************************************/
33
34 #ifndef dict0mem_h
35 #define dict0mem_h
36
37 #include "sql/dd/object_id.h"
38 #include "sql/dd/types/column.h"
39 #include "univ.i"
40 #ifdef UNIV_HOTBACKUP
41 #include "sql/dd/types/spatial_reference_system.h"
42 #endif /* UNIV_HOTBACKUP */
43 #include "btr0types.h"
44 #include "data0type.h"
45 #include "dict0types.h"
46 #include "mem0mem.h"
47 #include "rem0types.h"
48 #include "row0types.h"
49 #ifndef UNIV_HOTBACKUP
50 #include "lock0types.h"
51 #include "que0types.h"
52 #endif /* !UNIV_HOTBACKUP */
53 #include "hash0hash.h"
54 #include "sync0rw.h"
55 #include "trx0types.h"
56 #include "ut0byte.h"
57 #include "ut0mem.h"
58 #include "ut0rnd.h"
59 #ifndef UNIV_HOTBACKUP
60 #include "fts0fts.h"
61 #endif /* !UNIV_HOTBACKUP */
62 #include "buf0buf.h"
63 #include "gis0type.h"
64 #ifndef UNIV_HOTBACKUP
65 #include "os0once.h"
66 #endif /* !UNIV_HOTBACKUP */
67 #include "dict/mem.h"
68 #include "ut0new.h"
69
70 #include "sql/sql_const.h" /* MAX_KEY_LENGTH */
71
72 #include <algorithm>
73 #include <iterator>
74 #include <memory> /* std::unique_ptr */
75 #include <set>
76 #include <string>
77 #include <vector>
78
79 /* Forward declaration. */
80 struct ib_rbt_t;
81
82 /** Type flags of an index: OR'ing of the flags is allowed to define a
83 combination of types */
84 /* @{ */
85 #define DICT_CLUSTERED \
86 1 /*!< clustered index; for other than \
87 auto-generated clustered indexes, \
88 also DICT_UNIQUE will be set */
89 #define DICT_UNIQUE 2 /*!< unique index */
90 #define DICT_IBUF 8 /*!< insert buffer tree */
91 #define DICT_CORRUPT \
92 16 /*!< bit to store the corrupted flag \
93 in SYS_INDEXES.TYPE */
94 #define DICT_FTS \
95 32 /* FTS index; can't be combined with the \
96 other flags */
97 #define DICT_SPATIAL \
98 64 /* SPATIAL index; can't be combined with the \
99 other flags */
100 #define DICT_VIRTUAL 128 /* Index on Virtual column */
101
102 #define DICT_SDI \
103 256 /* Tablespace dictionary Index. Set only in \
104 in-memory index structure. */
105 #define DICT_MULTI_VALUE 512 /* Multi-value index */
106
107 #define DICT_IT_BITS \
108 10 /*!< number of bits used for \
109 SYS_INDEXES.TYPE */
110 /* @} */
111
112 #if 0 /* not implemented, retained for history */
113 /** Types for a table object */
114 #define DICT_TABLE_ORDINARY 1 /*!< ordinary table */
115 #define DICT_TABLE_CLUSTER_MEMBER 2
116 #define DICT_TABLE_CLUSTER \
117 3 /* this means that the table is \
118 really a cluster definition */
119 #endif
120
121 /* Table and tablespace flags are generally not used for the Antelope file
122 format except for the low order bit, which is used differently depending on
123 where the flags are stored.
124
125 ==================== Low order flags bit =========================
126 | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC
127 SYS_TABLES.TYPE | 1 | 1 | 1
128 dict_table_t::flags | 0 | 1 | 1
129 FSP_SPACE_FLAGS | 0 | 0 | 1
130 fil_space_t::flags | 0 | 0 | 1
131
132 Before the 5.1 plugin, SYS_TABLES.TYPE was always DICT_TABLE_ORDINARY (1)
133 and the tablespace flags field was always 0. In the 5.1 plugin, these fields
134 were repurposed to identify compressed and dynamic row formats.
135
136 The following types and constants describe the flags found in dict_table_t
137 and SYS_TABLES.TYPE. Similar flags found in fil_space_t and FSP_SPACE_FLAGS
138 are described in fsp0fsp.h. */
139
140 /* @{ */
141 /** dict_table_t::flags bit 0 is equal to 0 if the row format = Redundant */
142 #define DICT_TF_REDUNDANT 0 /*!< Redundant row format. */
143 /** dict_table_t::flags bit 0 is equal to 1 if the row format = Compact */
144 #define DICT_TF_COMPACT 1 /*!< Compact row format. */
145
146 /** This bitmask is used in SYS_TABLES.N_COLS to set and test whether
147 the Compact page format is used, i.e ROW_FORMAT != REDUNDANT */
148 #define DICT_N_COLS_COMPACT 0x80000000UL
149
150 /** Width of the COMPACT flag */
151 #define DICT_TF_WIDTH_COMPACT 1
152
153 /** Width of the ZIP_SSIZE flag */
154 #define DICT_TF_WIDTH_ZIP_SSIZE 4
155
156 /** Width of the ATOMIC_BLOBS flag. The ROW_FORMAT=REDUNDANT and
157 ROW_FORMAT=COMPACT broke up BLOB and TEXT fields, storing the first 768 bytes
158 in the clustered index. ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED
159 store the whole blob or text field off-page atomically.
160 Secondary indexes are created from this external data using row_ext_t
161 to cache the BLOB prefixes. */
162 #define DICT_TF_WIDTH_ATOMIC_BLOBS 1
163
164 /** If a table is created with the MYSQL option DATA DIRECTORY and
165 innodb-file-per-table, an older engine will not be able to find that table.
166 This flag prevents older engines from attempting to open the table and
167 allows InnoDB to update_create_info() accordingly. */
168 #define DICT_TF_WIDTH_DATA_DIR 1
169
170 /** Width of the SHARED tablespace flag.
171 It is used to identify tables that exist inside a shared general tablespace.
172 If a table is created with the TABLESPACE=tsname option, an older engine will
173 not be able to find that table. This flag prevents older engines from attempting
174 to open the table and allows InnoDB to quickly find the tablespace. */
175
176 #define DICT_TF_WIDTH_SHARED_SPACE 1
177
178 /** Width of all the currently known table flags */
179 #define DICT_TF_BITS \
180 (DICT_TF_WIDTH_COMPACT + DICT_TF_WIDTH_ZIP_SSIZE + \
181 DICT_TF_WIDTH_ATOMIC_BLOBS + DICT_TF_WIDTH_DATA_DIR + \
182 DICT_TF_WIDTH_SHARED_SPACE)
183
184 /** A mask of all the known/used bits in table flags */
185 #define DICT_TF_BIT_MASK (~(~0 << DICT_TF_BITS))
186
187 /** Zero relative shift position of the COMPACT field */
188 #define DICT_TF_POS_COMPACT 0
189 /** Zero relative shift position of the ZIP_SSIZE field */
190 #define DICT_TF_POS_ZIP_SSIZE (DICT_TF_POS_COMPACT + DICT_TF_WIDTH_COMPACT)
191 /** Zero relative shift position of the ATOMIC_BLOBS field */
192 #define DICT_TF_POS_ATOMIC_BLOBS \
193 (DICT_TF_POS_ZIP_SSIZE + DICT_TF_WIDTH_ZIP_SSIZE)
194 /** Zero relative shift position of the DATA_DIR field */
195 #define DICT_TF_POS_DATA_DIR \
196 (DICT_TF_POS_ATOMIC_BLOBS + DICT_TF_WIDTH_ATOMIC_BLOBS)
197 /** Zero relative shift position of the SHARED TABLESPACE field */
198 #define DICT_TF_POS_SHARED_SPACE (DICT_TF_POS_DATA_DIR + DICT_TF_WIDTH_DATA_DIR)
199 /** Zero relative shift position of the start of the UNUSED bits */
200 #define DICT_TF_POS_UNUSED \
201 (DICT_TF_POS_SHARED_SPACE + DICT_TF_WIDTH_SHARED_SPACE)
202
203 /** Bit mask of the COMPACT field */
204 #define DICT_TF_MASK_COMPACT \
205 ((~(~0U << DICT_TF_WIDTH_COMPACT)) << DICT_TF_POS_COMPACT)
206 /** Bit mask of the ZIP_SSIZE field */
207 #define DICT_TF_MASK_ZIP_SSIZE \
208 ((~(~0U << DICT_TF_WIDTH_ZIP_SSIZE)) << DICT_TF_POS_ZIP_SSIZE)
209 /** Bit mask of the ATOMIC_BLOBS field */
210 #define DICT_TF_MASK_ATOMIC_BLOBS \
211 ((~(~0U << DICT_TF_WIDTH_ATOMIC_BLOBS)) << DICT_TF_POS_ATOMIC_BLOBS)
212 /** Bit mask of the DATA_DIR field */
213 #define DICT_TF_MASK_DATA_DIR \
214 ((~(~0U << DICT_TF_WIDTH_DATA_DIR)) << DICT_TF_POS_DATA_DIR)
215 /** Bit mask of the SHARED_SPACE field */
216 #define DICT_TF_MASK_SHARED_SPACE \
217 ((~(~0U << DICT_TF_WIDTH_SHARED_SPACE)) << DICT_TF_POS_SHARED_SPACE)
218
219 /** Return the value of the COMPACT field */
220 #define DICT_TF_GET_COMPACT(flags) \
221 ((flags & DICT_TF_MASK_COMPACT) >> DICT_TF_POS_COMPACT)
222 /** Return the value of the ZIP_SSIZE field */
223 #define DICT_TF_GET_ZIP_SSIZE(flags) \
224 ((flags & DICT_TF_MASK_ZIP_SSIZE) >> DICT_TF_POS_ZIP_SSIZE)
225 /** Return the value of the ATOMIC_BLOBS field */
226 #define DICT_TF_HAS_ATOMIC_BLOBS(flags) \
227 ((flags & DICT_TF_MASK_ATOMIC_BLOBS) >> DICT_TF_POS_ATOMIC_BLOBS)
228 /** Return the value of the DATA_DIR field */
229 #define DICT_TF_HAS_DATA_DIR(flags) \
230 ((flags & DICT_TF_MASK_DATA_DIR) >> DICT_TF_POS_DATA_DIR)
231 /** Return the value of the SHARED_SPACE field */
232 #define DICT_TF_HAS_SHARED_SPACE(flags) \
233 ((flags & DICT_TF_MASK_SHARED_SPACE) >> DICT_TF_POS_SHARED_SPACE)
234 /** Return the contents of the UNUSED bits */
235 #define DICT_TF_GET_UNUSED(flags) (flags >> DICT_TF_POS_UNUSED)
236 /* @} */
237
238 /** @brief Table Flags set number 2.
239
240 These flags will be stored in SYS_TABLES.MIX_LEN. All unused flags
241 will be written as 0. The column may contain garbage for tables
242 created with old versions of InnoDB that only implemented
243 ROW_FORMAT=REDUNDANT. InnoDB engines do not check these flags
244 for unknown bits in order to protect backward incompatibility. */
245 /* @{ */
246 /** Total number of bits in table->flags2. */
247 #define DICT_TF2_BITS 11
248 #define DICT_TF2_UNUSED_BIT_MASK (~0U << DICT_TF2_BITS)
249 #define DICT_TF2_BIT_MASK ~DICT_TF2_UNUSED_BIT_MASK
250
251 /** TEMPORARY; TRUE for tables from CREATE TEMPORARY TABLE. */
252 #define DICT_TF2_TEMPORARY 1
253
254 /** The table has an internal defined DOC ID column */
255 #define DICT_TF2_FTS_HAS_DOC_ID 2
256
257 /** The table has an FTS index */
258 #define DICT_TF2_FTS 4
259
260 /** Need to add Doc ID column for FTS index build.
261 This is a transient bit for index build */
262 #define DICT_TF2_FTS_ADD_DOC_ID 8
263
264 /** This bit is used during table creation to indicate that it will
265 use its own tablespace instead of the system tablespace. */
266 #define DICT_TF2_USE_FILE_PER_TABLE 16
267
268 /** Set when we discard/detach the tablespace */
269 #define DICT_TF2_DISCARDED 32
270
271 /** Intrinsic table bit
272 Intrinsic table is table created internally by MySQL modules viz. Optimizer,
273 FTS, etc.... Intrinsic table has all the properties of the normal table except
274 it is not created by user and so not visible to end-user. */
275 #define DICT_TF2_INTRINSIC 128
276
277 /** Encryption table bit for innodb_file-per-table only. */
278 #define DICT_TF2_ENCRYPTION_FILE_PER_TABLE 256
279
280 /** FTS AUX hidden table bit. */
281 #define DICT_TF2_AUX 512
282
283 /** Table is opened by resurrected trx during crash recovery. */
284 #define DICT_TF2_RESURRECT_PREPARED 1024
285 /* @} */
286
287 #define DICT_TF2_FLAG_SET(table, flag) (table->flags2 |= (flag))
288
289 #define DICT_TF2_FLAG_IS_SET(table, flag) (table->flags2 & (flag))
290
291 #define DICT_TF2_FLAG_UNSET(table, flag) (table->flags2 &= ~(flag))
292
293 /** Tables could be chained together with Foreign key constraint. When
294 first load the parent table, we would load all of its descedents.
295 This could result in rescursive calls and out of stack error eventually.
296 DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads,
297 when exceeded, the child table will not be loaded. It will be loaded when
298 the foreign constraint check needs to be run. */
299 #define DICT_FK_MAX_RECURSIVE_LOAD 20
300
301 /** Similarly, when tables are chained together with foreign key constraints
302 with on cascading delete/update clause, delete from parent table could
303 result in recursive cascading calls. This defines the maximum number of
304 such cascading deletes/updates allowed. When exceeded, the delete from
305 parent table will fail, and user has to drop excessive foreign constraint
306 before proceeds. */
307 #define FK_MAX_CASCADE_DEL 15
308
309 /** Adds a virtual column definition to a table.
310 @param[in,out] table table
311 @param[in] heap temporary memory heap, or NULL. It is
312 used to store name when we have not finished
313 adding all columns. When all columns are
314 added, the whole name will copy to memory from
315 table->heap
316 @param[in] name column name
317 @param[in] mtype main datatype
318 @param[in] prtype precise type
319 @param[in] len length
320 @param[in] pos position in a table
321 @param[in] num_base number of base columns
322 @param[in] is_visible True if virtual column is visible to user
323 @return the virtual column definition */
324 dict_v_col_t *dict_mem_table_add_v_col(dict_table_t *table, mem_heap_t *heap,
325 const char *name, ulint mtype,
326 ulint prtype, ulint len, ulint pos,
327 ulint num_base, bool is_visible);
328
329 /** Adds a stored column definition to a table.
330 @param[in,out] table table
331 @param[in] num_base number of base columns. */
332 void dict_mem_table_add_s_col(dict_table_t *table, ulint num_base);
333
334 /** Renames a column of a table in the data dictionary cache. */
335 void dict_mem_table_col_rename(dict_table_t *table, /*!< in/out: table */
336 ulint nth_col, /*!< in: column index */
337 const char *from, /*!< in: old column name */
338 const char *to, /*!< in: new column name */
339 bool is_virtual);
340 /*!< in: if this is a virtual column */
341
342 /** This function poplulates a dict_index_t index memory structure with
343 supplied information.
344 @param[out] index index to be filled
345 @param[in] heap memory heap
346 @param[in] table_name table name
347 @param[in] index_name index name
348 @param[in] space space where the index tree is placed, the
349 clustered type ignored if the index is of the
350 clustered type
351 @param[in] type DICT_UNIQUE, DICT_CLUSTERED, ... ORed
352 @param[in] n_fields number of fields */
353 UNIV_INLINE
354 void dict_mem_fill_index_struct(dict_index_t *index, mem_heap_t *heap,
355 const char *table_name, const char *index_name,
356 ulint space, ulint type, ulint n_fields);
357
358 /** Frees an index memory object. */
359 void dict_mem_index_free(dict_index_t *index); /*!< in: index */
360 /** Creates and initializes a foreign constraint memory object.
361 @return own: foreign constraint struct */
362 dict_foreign_t *dict_mem_foreign_create(void);
363
364 /** Sets the foreign_table_name_lookup pointer based on the value of
365 lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup
366 will point to foreign_table_name. If 2, then another string is
367 allocated from the heap and set to lower case. */
368 void dict_mem_foreign_table_name_lookup_set(
369 dict_foreign_t *foreign, /*!< in/out: foreign struct */
370 ibool do_alloc); /*!< in: is an alloc needed */
371
372 /** Sets the referenced_table_name_lookup pointer based on the value of
373 lower_case_table_names. If that is 0 or 1, referenced_table_name_lookup
374 will point to referenced_table_name. If 2, then another string is
375 allocated from the heap and set to lower case. */
376 void dict_mem_referenced_table_name_lookup_set(
377 dict_foreign_t *foreign, /*!< in/out: foreign struct */
378 ibool do_alloc); /*!< in: is an alloc needed */
379
380 /** Fills the dependent virtual columns in a set.
381 Reason for being dependent are
382 1) FK can be present on base column of virtual columns
383 2) FK can be present on column which is a part of virtual index
384 @param[in,out] foreign foreign key information. */
385 void dict_mem_foreign_fill_vcol_set(dict_foreign_t *foreign);
386
387 /** Fill virtual columns set in each fk constraint present in the table.
388 @param[in,out] table innodb table object. */
389 void dict_mem_table_fill_foreign_vcol_set(dict_table_t *table);
390
391 /** Free the vcol_set from all foreign key constraint on the table.
392 @param[in,out] table innodb table object. */
393 void dict_mem_table_free_foreign_vcol_set(dict_table_t *table);
394
395 /** Create a temporary tablename like "#sql-ibtid-inc" where
396 tid = the Table ID
397 inc = a randomly initialized number that is incremented for each file
398 The table ID is a 64 bit integer, can use up to 20 digits, and is
399 initialized at bootstrap. The second number is 32 bits, can use up to 10
400 digits, and is initialized at startup to a randomly distributed number.
401 It is hoped that the combination of these two numbers will provide a
402 reasonably unique temporary file name.
403 @param[in] heap A memory heap
404 @param[in] dbtab Table name in the form database/table name
405 @param[in] id Table id
406 @return A unique temporary tablename suitable for InnoDB use */
407 char *dict_mem_create_temporary_tablename(mem_heap_t *heap, const char *dbtab,
408 table_id_t id);
409
410 /** Initialize dict memory variables */
411 void dict_mem_init(void);
412
413 /** SQL identifier name wrapper for pretty-printing */
414 class id_name_t {
415 public:
416 /** Default constructor */
id_name_t()417 id_name_t() : m_name() {}
418 /** Constructor
419 @param[in] name identifier to assign */
id_name_t(const char * name)420 explicit id_name_t(const char *name) : m_name(name) {}
421
422 /** Assignment operator
423 @param[in] name identifier to assign */
424 id_name_t &operator=(const char *name) {
425 m_name = name;
426 return (*this);
427 }
428
429 /** Implicit type conversion
430 @return the name */
431 operator const char *() const { return (m_name); }
432
433 /** Explicit type conversion
434 @return the name */
operator()435 const char *operator()() const { return (m_name); }
436
437 private:
438 /** The name in internal representation */
439 const char *m_name;
440 };
441
442 /** Table name wrapper for pretty-printing */
443 struct table_name_t {
444 /** The name in internal representation */
445 char *m_name;
446 };
447
448 /** Data structure for default value of a column in a table */
449 struct dict_col_default_t {
450 /** Pointer to the column itself */
451 dict_col_t *col;
452 /** Default value in bytes */
453 byte *value;
454 /** Length of default value */
455 size_t len;
456
457 bool operator==(const dict_col_default_t &other);
458 bool operator!=(const dict_col_default_t &other);
459 };
460
461 /** Data structure for a column in a table */
462 struct dict_col_t {
463 /*----------------------*/
464 /** The following are copied from dtype_t,
465 so that all bit-fields can be packed tightly. */
466 /* @{ */
467
468 /** Default value when this column was added instantly.
469 If this is not a instantly added column then this is nullptr. */
470 dict_col_default_t *instant_default;
471
472 unsigned prtype : 32; /*!< precise type; MySQL data
473 type, charset code, flags to
474 indicate nullability,
475 signedness, whether this is a
476 binary string, whether this is
477 a true VARCHAR where MySQL
478 uses 2 bytes to store the length */
479 unsigned mtype : 8; /*!< main data type */
480
481 /* the remaining fields do not affect alphabetical ordering: */
482
483 unsigned len : 16; /*!< length; for MySQL data this
484 is field->pack_length(),
485 except that for a >= 5.0.3
486 type true VARCHAR this is the
487 maximum byte length of the
488 string data (in addition to
489 the string, MySQL uses 1 or 2
490 bytes to store the string length) */
491
492 unsigned mbminmaxlen : 5; /*!< minimum and maximum length of a
493 character, in bytes;
494 DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
495 mbminlen=DATA_MBMINLEN(mbminmaxlen);
496 mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
497 /*----------------------*/
498 /* End of definitions copied from dtype_t */
499 /* @} */
500
501 unsigned ind : 10; /*!< table column position
502 (starting from 0) */
503 unsigned ord_part : 1; /*!< nonzero if this column
504 appears in the ordering fields
505 of an index */
506 unsigned max_prefix : 12; /*!< maximum index prefix length on
507 this column. Our current max limit is
508 3072 (REC_VERSION_56_MAX_INDEX_COL_LEN)
509 bytes. */
510
511 /* True, if the column is visible */
512 bool is_visible;
513
514 /** Returns the minimum size of the column.
515 @return minimum size */
get_min_sizedict_col_t516 ulint get_min_size() const {
517 return (dtype_get_min_size_low(mtype, prtype, len, mbminmaxlen));
518 }
519
520 /** Returns the maximum size of the column.
521 @return maximum size */
get_max_sizedict_col_t522 ulint get_max_size() const { return (dtype_get_max_size_low(mtype, len)); }
523
524 /** Check if a column is a virtual column
525 @return true if it is a virtual column, false otherwise */
is_virtualdict_col_t526 bool is_virtual() const { return (prtype & DATA_VIRTUAL); }
527
528 /** Check if a column is a multi-value virtual column
529 @return true if it is a multi-value virtual column, false otherwise */
is_multi_valuedict_col_t530 bool is_multi_value() const { return ((prtype & DATA_MULTI_VALUE) != 0); }
531
532 /** Check if a column is nullable
533 @return true if it is nullable, otherwise false */
is_nullabledict_col_t534 bool is_nullable() const { return ((prtype & DATA_NOT_NULL) == 0); }
535
536 /** Gets the column data type.
537 @param[out] type data type */
copy_typedict_col_t538 void copy_type(dtype_t *type) const {
539 ut_ad(type != nullptr);
540
541 type->mtype = mtype;
542 type->prtype = prtype;
543 type->len = len;
544 type->mbminmaxlen = mbminmaxlen;
545 }
546
547 /** Gets the minimum number of bytes per character.
548 @return minimum multi-byte char size, in bytes */
get_mbminlendict_col_t549 ulint get_mbminlen() const { return (DATA_MBMINLEN(mbminmaxlen)); }
550
551 /** Gets the maximum number of bytes per character.
552 @return maximum multi-byte char size, in bytes */
get_mbmaxlendict_col_t553 ulint get_mbmaxlen() const { return (DATA_MBMAXLEN(mbminmaxlen)); }
554
555 /** Sets the minimum and maximum number of bytes per character.
556 @param[in] mbminlen minimum multi byte character size, in bytes
557 @param[in] mbmaxlen mAXimum multi-byte character size, in bytes */
set_mbminmaxlendict_col_t558 void set_mbminmaxlen(ulint mbminlen, ulint mbmaxlen) {
559 ut_ad(mbminlen < DATA_MBMAX);
560 ut_ad(mbmaxlen < DATA_MBMAX);
561 ut_ad(mbminlen <= mbmaxlen);
562
563 mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
564 }
565
566 /** Returns the size of a fixed size column, 0 if not a fixed size column.
567 @param[in] comp nonzero=ROW_FORMAT=COMPACT
568 @return fixed size, or 0 */
get_fixed_sizedict_col_t569 ulint get_fixed_size(ulint comp) const {
570 return (dtype_get_fixed_size_low(mtype, prtype, len, mbminmaxlen, comp));
571 }
572
573 /** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
574 For fixed length types it is the fixed length of the type, otherwise 0.
575 @param[in] comp nonzero=ROW_FORMAT=COMPACT
576 @return SQL null storage size in ROW_FORMAT=REDUNDANT */
get_null_sizedict_col_t577 ulint get_null_size(ulint comp) const { return (get_fixed_size(comp)); }
578
579 /** Check whether the col is used in spatial index or regular index.
580 @return spatial status */
get_spatial_statusdict_col_t581 spatial_status_t get_spatial_status() const {
582 spatial_status_t spatial_status = SPATIAL_NONE;
583
584 /* Column is not a part of any index. */
585 if (!ord_part) {
586 return (spatial_status);
587 }
588
589 if (DATA_GEOMETRY_MTYPE(mtype)) {
590 if (max_prefix == 0) {
591 spatial_status = SPATIAL_ONLY;
592 } else {
593 /* Any regular index on a geometry column
594 should have a prefix. */
595 spatial_status = SPATIAL_MIXED;
596 }
597 }
598
599 return (spatial_status);
600 }
601
602 /** Set default value
603 @param[in] value Default value
604 @param[in] length Default value length
605 @param[in,out] heap Heap to allocate memory */
606 void set_default(const byte *value, size_t length, mem_heap_t *heap);
607
608 #ifdef UNIV_DEBUG
609 /** Assert that a column and a data type match.
610 param[in] type data type
611 @return true */
assert_equaldict_col_t612 bool assert_equal(const dtype_t *type) const {
613 ut_ad(type);
614
615 ut_ad(mtype == type->mtype);
616 ut_ad(prtype == type->prtype);
617 // ut_ad(col->len == type->len);
618 #ifndef UNIV_HOTBACKUP
619 ut_ad(mbminmaxlen == type->mbminmaxlen);
620 #endif /* !UNIV_HOTBACKUP */
621
622 return true;
623 }
624 #endif /* UNIV_DEBUG */
625 };
626
627 /** Index information put in a list of virtual column structure. Index
628 id and virtual column position in the index will be logged.
629 There can be multiple entries for a given index, with a different position. */
630 struct dict_v_idx_t {
631 /** active index on the column */
632 dict_index_t *index;
633
634 /** position in this index */
635 ulint nth_field;
636 };
637
638 /** Index list to put in dict_v_col_t */
639 typedef std::list<dict_v_idx_t, ut_allocator<dict_v_idx_t>> dict_v_idx_list;
640
641 /** Data structure for a virtual column in a table */
642 struct dict_v_col_t {
643 /** column structure */
644 dict_col_t m_col;
645
646 /** array of base column ptr */
647 dict_col_t **base_col;
648
649 /** number of base columns */
650 ulint num_base;
651
652 /** column pos in table */
653 ulint v_pos;
654
655 /** Virtual index list, and column position in the index,
656 the allocated memory is not from table->heap, nor it is
657 tracked by dict_sys->size */
658 dict_v_idx_list *v_indexes;
659 };
660
661 /** Data structure for newly added virtual column in a table */
662 struct dict_add_v_col_t {
663 /** number of new virtual column */
664 ulint n_v_col;
665
666 /** column structures */
667 const dict_v_col_t *v_col;
668
669 /** new col names */
670 const char **v_col_name;
671 };
672
673 /** Data structure for a stored column in a table. */
674 struct dict_s_col_t {
675 /** Stored column ptr */
676 dict_col_t *m_col;
677 /** array of base col ptr */
678 dict_col_t **base_col;
679 /** number of base columns */
680 ulint num_base;
681 /** column pos in table */
682 ulint s_pos;
683 };
684
685 /** list to put stored column for dict_table_t */
686 typedef std::list<dict_s_col_t, ut_allocator<dict_s_col_t>> dict_s_col_list;
687
688 /** @brief DICT_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and
689 is the maximum indexed column length (or indexed prefix length) in
690 ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT. Also, in any format,
691 any fixed-length field that is longer than this will be encoded as
692 a variable-length field.
693
694 It is set to 3*256, so that one can create a column prefix index on
695 256 characters of a TEXT or VARCHAR column also in the UTF-8
696 charset. In that charset, a character may take at most 3 bytes. This
697 constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
698 files would be at risk! */
699 #define DICT_ANTELOPE_MAX_INDEX_COL_LEN REC_ANTELOPE_MAX_INDEX_COL_LEN
700
701 /** Find out maximum indexed column length by its table format.
702 For ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT, the maximum
703 field length is REC_ANTELOPE_MAX_INDEX_COL_LEN - 1 (767). For
704 ROW_FORMAT=COMPRESSED and ROW_FORMAT=DYNAMIC, the length could
705 be REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes */
706 #define DICT_MAX_FIELD_LEN_BY_FORMAT(table) \
707 (dict_table_has_atomic_blobs(table) ? REC_VERSION_56_MAX_INDEX_COL_LEN \
708 : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1)
709
710 #define DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags) \
711 (DICT_TF_HAS_ATOMIC_BLOBS(flags) ? REC_VERSION_56_MAX_INDEX_COL_LEN \
712 : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1)
713
714 /** Defines the maximum fixed length column size */
715 #define DICT_MAX_FIXED_COL_LEN DICT_ANTELOPE_MAX_INDEX_COL_LEN
716
717 /** Data structure for a field in an index */
718 struct dict_field_t {
dict_field_tdict_field_t719 dict_field_t() : col(nullptr), prefix_len(0), fixed_len(0), is_ascending(0) {}
720
721 dict_col_t *col; /*!< pointer to the table column */
722 id_name_t name; /*!< name of the column */
723 unsigned prefix_len : 12; /*!< 0 or the length of the column
724 prefix in bytes in a MySQL index of
725 type, e.g., INDEX (textcol(25));
726 must be smaller than
727 DICT_MAX_FIELD_LEN_BY_FORMAT;
728 NOTE that in the UTF-8 charset, MySQL
729 sets this to (mbmaxlen * the prefix len)
730 in UTF-8 chars */
731 unsigned fixed_len : 10; /*!< 0 or the fixed length of the
732 column if smaller than
733 DICT_ANTELOPE_MAX_INDEX_COL_LEN */
734 unsigned is_ascending : 1; /*!< 0=DESC, 1=ASC */
735 };
736
737 /** PADDING HEURISTIC BASED ON LINEAR INCREASE OF PADDING TO AVOID
738 COMPRESSION FAILURES
739 (Note: this is relevant only for compressed indexes)
740 GOAL: Avoid compression failures by maintaining information about the
741 compressibility of data. If data is not very compressible then leave
742 some extra space 'padding' in the uncompressed page making it more
743 likely that compression of less than fully packed uncompressed page will
744 succeed.
745
746 This padding heuristic works by increasing the pad linearly until the
747 desired failure rate is reached. A "round" is a fixed number of
748 compression operations.
749 After each round, the compression failure rate for that round is
750 computed. If the failure rate is too high, then padding is incremented
751 by a fixed value, otherwise it's left intact.
752 If the compression failure is lower than the desired rate for a fixed
753 number of consecutive rounds, then the padding is decreased by a fixed
754 value. This is done to prevent overshooting the padding value,
755 and to accommodate the possible change in data compressibility. */
756
757 /** Number of zip ops in one round. */
758 #define ZIP_PAD_ROUND_LEN (128)
759
760 /** Number of successful rounds after which the padding is decreased */
761 #define ZIP_PAD_SUCCESSFUL_ROUND_LIMIT (5)
762
763 /** Amount by which padding is increased. */
764 #define ZIP_PAD_INCR (128)
765
766 /** Percentage of compression failures that are allowed in a single
767 round */
768 extern ulong zip_failure_threshold_pct;
769
770 /** Maximum percentage of a page that can be allowed as a pad to avoid
771 compression failures */
772 extern ulong zip_pad_max;
773
774 /** Data structure to hold information about about how much space in
775 an uncompressed page should be left as padding to avoid compression
776 failures. This estimate is based on a self-adapting heuristic. */
777 struct zip_pad_info_t {
778 SysMutex *mutex; /*!< mutex protecting the info */
779 ulint pad; /*!< number of bytes used as pad */
780 ulint success; /*!< successful compression ops during
781 current round */
782 ulint failure; /*!< failed compression ops during
783 current round */
784 ulint n_rounds; /*!< number of currently successful
785 rounds */
786 #ifndef UNIV_HOTBACKUP
787 volatile os_once::state_t mutex_created;
788 /*!< Creation state of mutex member */
789 #endif /* !UNIV_HOTBACKUP */
790 };
791
792 /** If key is fixed length key then cache the record offsets on first
793 computation. This will help save computation cycle that generate same
794 redundant data. */
795 class rec_cache_t {
796 public:
797 /** Constructor */
rec_cache_t()798 rec_cache_t()
799 : rec_size(),
800 offsets(),
801 sz_of_offsets(),
802 fixed_len_key(),
803 offsets_cached(),
804 key_has_null_cols() {
805 /* Do Nothing. */
806 }
807
808 public:
809 /** Record size. (for fixed length key record size is constant) */
810 ulint rec_size;
811
812 /** Holds reference to cached offsets for record. */
813 ulint *offsets;
814
815 /** Size of offset array */
816 uint32_t sz_of_offsets;
817
818 /** If true, then key is fixed length key. */
819 bool fixed_len_key;
820
821 /** If true, then offset has been cached for re-use. */
822 bool offsets_cached;
823
824 /** If true, then key part can have columns that can take
825 NULL values. */
826 bool key_has_null_cols;
827 };
828
829 /** Cache position of last inserted or selected record by caching record
830 and holding reference to the block where record resides.
831 Note: We don't commit mtr and hold it beyond a transaction lifetime as this is
832 a special case (intrinsic table) that are not shared accross connection. */
833 class last_ops_cur_t {
834 public:
835 /** Constructor */
last_ops_cur_t()836 last_ops_cur_t() : rec(), block(), mtr(), disable_caching(), invalid() {
837 /* Do Nothing. */
838 }
839
840 /* Commit mtr and re-initialize cache record and block to NULL. */
release()841 void release() {
842 if (mtr.is_active()) {
843 mtr_commit(&mtr);
844 }
845 rec = nullptr;
846 block = nullptr;
847 invalid = false;
848 }
849
850 public:
851 /** last inserted/selected record. */
852 rec_t *rec;
853
854 /** block where record reside. */
855 buf_block_t *block;
856
857 /** active mtr that will be re-used for next insert/select. */
858 mtr_t mtr;
859
860 /** disable caching. (disabled when table involves blob/text.) */
861 bool disable_caching;
862
863 /** If index structure is undergoing structural change viz.
864 split then invalidate the cached position as it would be no more
865 remain valid. Will be re-cached on post-split insert. */
866 bool invalid;
867 };
868
869 /** "GEN_CLUST_INDEX" is the name reserved for InnoDB default
870 system clustered index when there is no primary key. */
871 const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX";
872
873 namespace dd {
874 class Spatial_reference_system;
875 }
876
877 /** Data structure for an index. Most fields will be
878 initialized to 0, NULL or FALSE in dict_mem_index_create(). */
879 struct dict_index_t {
880 space_index_t id; /*!< id of the index */
881 mem_heap_t *heap; /*!< memory heap */
882 id_name_t name; /*!< index name */
883 const char *table_name; /*!< table name */
884 dict_table_t *table; /*!< back pointer to table */
885 unsigned space : 32;
886 /*!< space where the index tree is placed */
887 unsigned page : 32; /*!< index tree root page number */
888 unsigned merge_threshold : 6;
889 /*!< In the pessimistic delete, if the page
890 data size drops below this limit in percent,
891 merging it to a neighbor is tried */
892 #define DICT_INDEX_MERGE_THRESHOLD_DEFAULT 50
893 unsigned type : DICT_IT_BITS;
894 /*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
895 DICT_IBUF, DICT_CORRUPT) */
896 #define MAX_KEY_LENGTH_BITS 12
897 unsigned trx_id_offset : MAX_KEY_LENGTH_BITS;
898 /*!< position of the trx id column
899 in a clustered index record, if the fields
900 before it are known to be of a fixed size,
901 0 otherwise */
902 #if (1 << MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
903 #error(1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
904 #endif
905 unsigned n_user_defined_cols : 10;
906 /*!< number of columns the user defined to
907 be in the index: in the internal
908 representation we add more columns */
909 unsigned allow_duplicates : 1;
910 /*!< if true, allow duplicate values
911 even if index is created with unique
912 constraint */
913 unsigned nulls_equal : 1;
914 /*!< if true, SQL NULL == SQL NULL */
915 unsigned disable_ahi : 1;
916 /*!< if true, then disable AHI. Currently
917 limited to intrinsic temporary table and SDI
918 table as index id is not unique for such table
919 which is one of the validation criterion for
920 ahi. */
921 unsigned n_uniq : 10; /*!< number of fields from the beginning
922 which are enough to determine an index
923 entry uniquely */
924 unsigned n_def : 10; /*!< number of fields defined so far */
925 unsigned n_fields : 10; /*!< number of fields in the index */
926 unsigned n_nullable : 10; /*!< number of nullable fields */
927 unsigned n_instant_nullable : 10;
928 /*!< number of nullable fields before first
929 instant ADD COLUMN applied to this table.
930 This is valid only when has_instant_cols() is true */
931 unsigned cached : 1; /*!< TRUE if the index object is in the
932 dictionary cache */
933 unsigned to_be_dropped : 1;
934 /*!< TRUE if the index is to be dropped;
935 protected by dict_operation_lock */
936 unsigned online_status : 2;
937 /*!< enum online_index_status.
938 Transitions from ONLINE_INDEX_COMPLETE (to
939 ONLINE_INDEX_CREATION) are protected
940 by dict_operation_lock and
941 dict_sys->mutex. Other changes are
942 protected by index->lock. */
943 unsigned uncommitted : 1;
944 /*!< a flag that is set for secondary indexes
945 that have not been committed to the
946 data dictionary yet */
947 unsigned instant_cols : 1;
948 /*!< TRUE if the index is clustered index and it has some
949 instant columns */
950 uint32_t srid; /* spatial reference id */
951 bool srid_is_valid;
952 /* says whether SRID is valid - it cane be
953 undefined */
954 std::unique_ptr<dd::Spatial_reference_system> rtr_srs;
955 /*!< Cached spatial reference system dictionary
956 entry used by R-tree indexes. */
957
958 #ifdef UNIV_DEBUG
959 uint32_t magic_n; /*!< magic number */
960 /** Value of dict_index_t::magic_n */
961 #define DICT_INDEX_MAGIC_N 76789786
962 #endif
963 dict_field_t *fields; /*!< array of field descriptions */
964 #ifndef UNIV_HOTBACKUP
965 st_mysql_ftparser *parser; /*!< fulltext parser plugin */
966 bool is_ngram;
967 /*!< true if it's ngram parser */
968 bool has_new_v_col;
969 /*!< whether it has a newly added virtual
970 column in ALTER */
971 bool hidden; /*!< if the index is an hidden index */
972 #endif /* !UNIV_HOTBACKUP */
973 UT_LIST_NODE_T(dict_index_t)
974 indexes; /*!< list of indexes of the table */
975 btr_search_t *search_info;
976 /*!< info used in optimistic searches */
977 #ifndef UNIV_HOTBACKUP
978 row_log_t *online_log;
979 /*!< the log of modifications
980 during online index creation;
981 valid when online_status is
982 ONLINE_INDEX_CREATION */
983 /*----------------------*/
984 /** Statistics for query optimization */
985 /* @{ */
986 ib_uint64_t *stat_n_diff_key_vals;
987 /*!< approximate number of different
988 key values for this index, for each
989 n-column prefix where 1 <= n <=
990 dict_get_n_unique(index) (the array is
991 indexed from 0 to n_uniq-1); we
992 periodically calculate new
993 estimates */
994 ib_uint64_t *stat_n_sample_sizes;
995 /*!< number of pages that were sampled
996 to calculate each of stat_n_diff_key_vals[],
997 e.g. stat_n_sample_sizes[3] pages were sampled
998 to get the number stat_n_diff_key_vals[3]. */
999 ib_uint64_t *stat_n_non_null_key_vals;
1000 /* approximate number of non-null key values
1001 for this index, for each column where
1002 1 <= n <= dict_get_n_unique(index) (the array
1003 is indexed from 0 to n_uniq-1); This
1004 is used when innodb_stats_method is
1005 "nulls_ignored". */
1006 ulint stat_index_size;
1007 /*!< approximate index size in
1008 database pages */
1009 #endif /* !UNIV_HOTBACKUP */
1010 ulint stat_n_leaf_pages;
1011 /*!< approximate number of leaf pages in the
1012 index tree */
1013 /* @} */
1014 last_ops_cur_t *last_ins_cur;
1015 /*!< cache the last insert position.
1016 Currently limited to auto-generated
1017 clustered index on intrinsic table only. */
1018 last_ops_cur_t *last_sel_cur;
1019 /*!< cache the last selected position
1020 Currently limited to intrinsic table only. */
1021 rec_cache_t rec_cache;
1022 /*!< cache the field that needs to be
1023 re-computed on each insert.
1024 Limited to intrinsic table as this is common
1025 share and can't be used without protection
1026 if table is accessible to multiple-threads. */
1027 rtr_ssn_t rtr_ssn; /*!< Node sequence number for RTree */
1028 rtr_info_track_t *rtr_track; /*!< tracking all R-Tree search cursors */
1029 trx_id_t trx_id; /*!< id of the transaction that created this
1030 index, or 0 if the index existed
1031 when InnoDB was started up */
1032 zip_pad_info_t zip_pad; /*!< Information about state of
1033 compression failures and successes */
1034 rw_lock_t lock; /*!< read-write lock protecting the
1035 upper levels of the index tree */
1036 bool fill_dd; /*!< Flag whether need to fill dd tables
1037 when it's a fulltext index. */
1038
1039 /** Determine if the index has been committed to the
1040 data dictionary.
1041 @return whether the index definition has been committed */
is_committeddict_index_t1042 bool is_committed() const {
1043 ut_ad(!uncommitted || !(type & DICT_CLUSTERED));
1044 return (UNIV_LIKELY(!uncommitted));
1045 }
1046
1047 /** Flag an index committed or uncommitted.
1048 @param[in] committed whether the index is committed */
set_committeddict_index_t1049 void set_committed(bool committed) {
1050 ut_ad(!to_be_dropped);
1051 ut_ad(committed || !(type & DICT_CLUSTERED));
1052 uncommitted = !committed;
1053 }
1054
1055 /** Get the next index.
1056 @return next index
1057 @retval NULL if this was the last index */
nextdict_index_t1058 const dict_index_t *next() const {
1059 const dict_index_t *next = UT_LIST_GET_NEXT(indexes, this);
1060 ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1061 return (next);
1062 }
1063 /** Get the next index.
1064 @return next index
1065 @retval NULL if this was the last index */
nextdict_index_t1066 dict_index_t *next() {
1067 return (const_cast<dict_index_t *>(
1068 const_cast<const dict_index_t *>(this)->next()));
1069 }
1070
1071 /** Check whether the index is corrupted.
1072 @return true if index is corrupted, otherwise false */
is_corrupteddict_index_t1073 bool is_corrupted() const {
1074 ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1075
1076 return (type & DICT_CORRUPT);
1077 }
1078
1079 /* Check whether the index is the clustered index
1080 @return nonzero for clustered index, zero for other indexes */
1081
is_clustereddict_index_t1082 bool is_clustered() const {
1083 ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1084
1085 return (type & DICT_CLUSTERED);
1086 }
1087
1088 /** Check whether the index is the multi-value index
1089 @return nonzero for multi-value index, zero for other indexes */
is_multi_valuedict_index_t1090 bool is_multi_value() const {
1091 ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1092
1093 return (type & DICT_MULTI_VALUE);
1094 }
1095
1096 /** Returns the minimum data size of an index record.
1097 @return minimum data size in bytes */
get_min_sizedict_index_t1098 ulint get_min_size() const {
1099 ulint size = 0;
1100
1101 for (unsigned i = 0; i < n_fields; i++) {
1102 size += get_col(i)->get_min_size();
1103 }
1104
1105 return (size);
1106 }
1107
1108 /** Check whether index can be used by transaction
1109 @param[in] trx transaction*/
1110 bool is_usable(const trx_t *trx) const;
1111
1112 /** Check whether index has any instantly added columns
1113 @return true if this is instant affected, otherwise false */
has_instant_colsdict_index_t1114 bool has_instant_cols() const { return (instant_cols); }
1115
1116 /** Returns the number of nullable fields before specified
1117 nth field
1118 @param[in] nth nth field to check */
get_n_nullable_beforedict_index_t1119 uint32_t get_n_nullable_before(uint32_t nth) const {
1120 uint32_t nullable = n_nullable;
1121
1122 ut_ad(nth <= n_fields);
1123
1124 for (uint32_t i = nth; i < n_fields; ++i) {
1125 if (get_field(i)->col->is_nullable()) {
1126 --nullable;
1127 }
1128 }
1129
1130 return (nullable);
1131 }
1132
1133 /** Returns the number of fields before first instant ADD COLUMN */
1134 uint32_t get_instant_fields() const;
1135
1136 /** Adds a field definition to an index. NOTE: does not take a copy
1137 of the column name if the field is a column. The memory occupied
1138 by the column name may be released only after publishing the index.
1139 @param[in] name_arg column name
1140 @param[in] prefix_len 0 or the column prefix length in a MySQL index
1141 like INDEX (textcol(25))
1142 @param[in] is_ascending true=ASC, false=DESC */
add_fielddict_index_t1143 void add_field(const char *name_arg, ulint prefix_len, bool is_ascending) {
1144 dict_field_t *field;
1145
1146 ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1147
1148 n_def++;
1149
1150 field = get_field(n_def - 1);
1151
1152 field->name = name_arg;
1153 field->prefix_len = (unsigned int)prefix_len;
1154 field->is_ascending = is_ascending;
1155 }
1156
1157 /** Gets the nth field of an index.
1158 @param[in] pos position of field
1159 @return pointer to field object */
get_fielddict_index_t1160 dict_field_t *get_field(ulint pos) const {
1161 ut_ad(pos < n_def);
1162 ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1163
1164 return (fields + pos);
1165 }
1166
1167 /** Gets pointer to the nth column in an index.
1168 @param[in] pos position of the field
1169 @return column */
get_coldict_index_t1170 const dict_col_t *get_col(ulint pos) const { return (get_field(pos)->col); }
1171
1172 /** Gets the column number the nth field in an index.
1173 @param[in] pos position of the field
1174 @return column number */
1175 ulint get_col_no(ulint pos) const;
1176
1177 /** Returns the position of a system column in an index.
1178 @param[in] type DATA_ROW_ID, ...
1179 @return position, ULINT_UNDEFINED if not contained */
1180 ulint get_sys_col_pos(ulint type) const;
1181
1182 /** Looks for column n in an index.
1183 @param[in] n column number
1184 @param[in] inc_prefix true=consider column prefixes too
1185 @param[in] is_virtual true==virtual column
1186 @return position in internal representation of the index;
1187 ULINT_UNDEFINED if not contained */
1188 ulint get_col_pos(ulint n, bool inc_prefix = false,
1189 bool is_virtual = false) const;
1190
1191 /** Get the default value of nth field and its length if exists.
1192 If not exists, both the return value is nullptr and length is 0.
1193 @param[in] nth nth field to get
1194 @param[in,out] length length of the default value
1195 @return the default value data of nth field */
get_nth_defaultdict_index_t1196 const byte *get_nth_default(ulint nth, ulint *length) const {
1197 ut_ad(nth < n_fields);
1198 ut_ad(get_instant_fields() <= nth);
1199 const dict_col_t *col = get_col(nth);
1200 if (col->instant_default == nullptr) {
1201 *length = 0;
1202 return (nullptr);
1203 }
1204
1205 *length = col->instant_default->len;
1206 ut_ad(*length == 0 || *length == UNIV_SQL_NULL ||
1207 col->instant_default->value != nullptr);
1208 return (col->instant_default->value);
1209 }
1210
1211 /** Sets srid and srid_is_valid values
1212 @param[in] srid_value value of SRID, may be garbage
1213 if srid_is_valid_value = false
1214 @param[in] srid_is_valid_value value of srid_is_valid */
fill_srid_valuedict_index_t1215 void fill_srid_value(uint32_t srid_value, bool srid_is_valid_value) {
1216 srid_is_valid = srid_is_valid_value;
1217 srid = srid_value;
1218 }
1219
1220 /** Check if the underlying table is compressed.
1221 @return true if compressed, false otherwise. */
1222 bool is_compressed() const;
1223
1224 /** Check if a multi-value index is built on specified multi-value
1225 virtual column. Please note that there could be only one multi-value
1226 virtual column on the multi-value index, but not necessary the first
1227 field of the index.
1228 @param[in] mv_col multi-value virtual column
1229 @return non-zero means the column is on the index and this is the
1230 nth position of the column, zero means it's not on the index */
has_multi_value_coldict_index_t1231 uint32_t has_multi_value_col(const dict_v_col_t *mv_col) const {
1232 ut_ad(is_multi_value());
1233 for (uint32_t i = 0; i < n_fields; ++i) {
1234 const dict_col_t *col = get_col(i);
1235 if (mv_col->m_col.ind == col->ind) {
1236 return (i + 1);
1237 }
1238
1239 /* Only one multi-value field, if not match then no match. */
1240 if (col->is_multi_value()) {
1241 break;
1242 }
1243 }
1244
1245 return (0);
1246 }
1247
1248 public:
1249 /** Get the page size of the tablespace to which this index belongs.
1250 @return the page size. */
1251 page_size_t get_page_size() const;
1252
1253 /** Get the space id of the tablespace to which this index belongs.
1254 @return the space id. */
space_iddict_index_t1255 space_id_t space_id() const { return space; }
1256 };
1257
1258 /** The status of online index creation */
1259 enum online_index_status {
1260 /** the index is complete and ready for access */
1261 ONLINE_INDEX_COMPLETE = 0,
1262 /** the index is being created, online
1263 (allowing concurrent modifications) */
1264 ONLINE_INDEX_CREATION,
1265 /** secondary index creation was aborted and the index
1266 should be dropped as soon as index->table->n_ref_count reaches 0,
1267 or online table rebuild was aborted and the clustered index
1268 of the original table should soon be restored to
1269 ONLINE_INDEX_COMPLETE */
1270 ONLINE_INDEX_ABORTED,
1271 /** the online index creation was aborted, the index was
1272 dropped from the data dictionary and the tablespace, and it
1273 should be dropped from the data dictionary cache as soon as
1274 index->table->n_ref_count reaches 0. */
1275 ONLINE_INDEX_ABORTED_DROPPED
1276 };
1277
1278 /** Set to store the virtual columns which are affected by Foreign
1279 key constraint. */
1280 typedef std::set<dict_v_col_t *, std::less<dict_v_col_t *>,
1281 ut_allocator<dict_v_col_t *>>
1282 dict_vcol_set;
1283
1284 /** Data structure for a foreign key constraint; an example:
1285 FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D). Most fields will be
1286 initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
1287 struct dict_foreign_t {
1288 mem_heap_t *heap; /*!< this object is allocated from
1289 this memory heap */
1290 char *id; /*!< id of the constraint as a
1291 null-terminated string */
1292 unsigned n_fields : 10; /*!< number of indexes' first fields
1293 for which the foreign key
1294 constraint is defined: we allow the
1295 indexes to contain more fields than
1296 mentioned in the constraint, as long
1297 as the first fields are as mentioned */
1298 unsigned type : 6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
1299 or DICT_FOREIGN_ON_DELETE_SET_NULL */
1300 char *foreign_table_name; /*!< foreign table name */
1301 char *foreign_table_name_lookup;
1302 /*!< foreign table name used for dict lookup */
1303 dict_table_t *foreign_table; /*!< table where the foreign key is */
1304 const char **foreign_col_names; /*!< names of the columns in the
1305 foreign key */
1306 char *referenced_table_name; /*!< referenced table name */
1307 char *referenced_table_name_lookup;
1308 /*!< referenced table name for dict lookup*/
1309 dict_table_t *referenced_table; /*!< table where the referenced key
1310 is */
1311 const char **referenced_col_names; /*!< names of the referenced
1312 columns in the referenced table */
1313 dict_index_t *foreign_index; /*!< foreign index; we require that
1314 both tables contain explicitly defined
1315 indexes for the constraint: InnoDB
1316 does not generate new indexes
1317 implicitly */
1318 dict_index_t *referenced_index; /*!< referenced index */
1319
1320 dict_vcol_set *v_cols; /*!< set of virtual columns affected
1321 by foreign key constraint. */
1322 };
1323
1324 std::ostream &operator<<(std::ostream &out, const dict_foreign_t &foreign);
1325
1326 struct dict_foreign_print {
dict_foreign_printdict_foreign_print1327 dict_foreign_print(std::ostream &out) : m_out(out) {}
1328
operatordict_foreign_print1329 void operator()(const dict_foreign_t *foreign) { m_out << *foreign; }
1330
1331 private:
1332 std::ostream &m_out;
1333 };
1334
1335 /** Compare two dict_foreign_t objects using their ids. Used in the ordering
1336 of dict_table_t::foreign_set and dict_table_t::referenced_set. It returns
1337 true if the first argument is considered to go before the second in the
1338 strict weak ordering it defines, and false otherwise. */
1339 struct dict_foreign_compare {
operatordict_foreign_compare1340 bool operator()(const dict_foreign_t *lhs, const dict_foreign_t *rhs) const {
1341 return (ut_strcmp(lhs->id, rhs->id) < 0);
1342 }
1343 };
1344
1345 /** A function object to find a foreign key with the given index as the
1346 referenced index. Return the foreign key with matching criteria or NULL */
1347 struct dict_foreign_with_index {
dict_foreign_with_indexdict_foreign_with_index1348 dict_foreign_with_index(const dict_index_t *index) : m_index(index) {}
1349
operatordict_foreign_with_index1350 bool operator()(const dict_foreign_t *foreign) const {
1351 return (foreign->referenced_index == m_index);
1352 }
1353
1354 const dict_index_t *m_index;
1355 };
1356
1357 /* A function object to check if the foreign constraint is between different
1358 tables. Returns true if foreign key constraint is between different tables,
1359 false otherwise. */
1360 struct dict_foreign_different_tables {
operatordict_foreign_different_tables1361 bool operator()(const dict_foreign_t *foreign) const {
1362 return (foreign->foreign_table != foreign->referenced_table);
1363 }
1364 };
1365
1366 typedef std::set<dict_foreign_t *, dict_foreign_compare,
1367 ut_allocator<dict_foreign_t *>>
1368 dict_foreign_set;
1369
1370 std::ostream &operator<<(std::ostream &out, const dict_foreign_set &fk_set);
1371
1372 /** Function object to check if a foreign key object is there
1373 in the given foreign key set or not. It returns true if the
1374 foreign key is not found, false otherwise */
1375 struct dict_foreign_not_exists {
dict_foreign_not_existsdict_foreign_not_exists1376 dict_foreign_not_exists(const dict_foreign_set &obj_) : m_foreigns(obj_) {}
1377
1378 /* Return true if the given foreign key is not found */
operatordict_foreign_not_exists1379 bool operator()(dict_foreign_t *const &foreign) const {
1380 return (m_foreigns.find(foreign) == m_foreigns.end());
1381 }
1382
1383 private:
1384 const dict_foreign_set &m_foreigns;
1385 };
1386
1387 /** Validate the search order in the foreign key set.
1388 @param[in] fk_set the foreign key set to be validated
1389 @return true if search order is fine in the set, false otherwise. */
1390 bool dict_foreign_set_validate(const dict_foreign_set &fk_set);
1391
1392 /** Validate the search order in the foreign key sets of the table
1393 (foreign_set and referenced_set).
1394 @param[in] table table whose foreign key sets are to be validated
1395 @return true if foreign key sets are fine, false otherwise. */
1396 bool dict_foreign_set_validate(const dict_table_t &table);
1397
1398 /** Frees a foreign key struct. */
dict_foreign_free(dict_foreign_t * foreign)1399 inline void dict_foreign_free(
1400 dict_foreign_t *foreign) /*!< in, own: foreign key struct */
1401 {
1402 if (foreign->v_cols != nullptr) {
1403 UT_DELETE(foreign->v_cols);
1404 }
1405
1406 mem_heap_free(foreign->heap);
1407 }
1408
1409 /** The destructor will free all the foreign key constraints in the set
1410 by calling dict_foreign_free() on each of the foreign key constraints.
1411 This is used to free the allocated memory when a local set goes out
1412 of scope. */
1413 struct dict_foreign_set_free {
dict_foreign_set_freedict_foreign_set_free1414 dict_foreign_set_free(const dict_foreign_set &foreign_set)
1415 : m_foreign_set(foreign_set) {}
1416
~dict_foreign_set_freedict_foreign_set_free1417 ~dict_foreign_set_free() {
1418 std::for_each(m_foreign_set.begin(), m_foreign_set.end(),
1419 dict_foreign_free);
1420 }
1421
1422 const dict_foreign_set &m_foreign_set;
1423 };
1424
1425 /** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
1426 a foreign key constraint is enforced, therefore RESTRICT just means no flag */
1427 /* @{ */
1428 #define DICT_FOREIGN_ON_DELETE_CASCADE 1 /*!< ON DELETE CASCADE */
1429 #define DICT_FOREIGN_ON_DELETE_SET_NULL 2 /*!< ON DELETE SET NULL */
1430 #define DICT_FOREIGN_ON_UPDATE_CASCADE 4 /*!< ON UPDATE CASCADE */
1431 #define DICT_FOREIGN_ON_UPDATE_SET_NULL 8 /*!< ON UPDATE SET NULL */
1432 #define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 /*!< ON DELETE NO ACTION */
1433 #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 /*!< ON UPDATE NO ACTION */
1434 /* @} */
1435
1436 /** Display an identifier.
1437 @param[in,out] s output stream
1438 @param[in] id_name SQL identifier (other than table name)
1439 @return the output stream */
1440 std::ostream &operator<<(std::ostream &s, const id_name_t &id_name);
1441
1442 /** Display a table name.
1443 @param[in,out] s output stream
1444 @param[in] table_name table name
1445 @return the output stream */
1446 std::ostream &operator<<(std::ostream &s, const table_name_t &table_name);
1447
1448 #ifndef UNIV_HOTBACKUP
1449 /** List of locks that different transactions have acquired on a table. This
1450 list has a list node that is embedded in a nested union/structure. We have to
1451 generate a specific template for it. */
1452
1453 typedef ut_list_base<lock_t, ut_list_node<lock_t> lock_table_t::*>
1454 table_lock_list_t;
1455 #endif /* !UNIV_HOTBACKUP */
1456
1457 /** mysql template structure defined in row0mysql.cc */
1458 struct mysql_row_templ_t;
1459
1460 /** Structure defines template related to virtual columns and
1461 their base columns */
1462 struct dict_vcol_templ_t {
1463 /** number of regular columns */
1464 ulint n_col;
1465
1466 /** number of virtual columns */
1467 ulint n_v_col;
1468
1469 /** array of templates for virtual col and their base columns */
1470 mysql_row_templ_t **vtempl;
1471
1472 /** table's database name */
1473 std::string db_name;
1474
1475 /** table name */
1476 std::string tb_name;
1477
1478 /** share->table_name */
1479 std::string share_name;
1480
1481 /** MySQL record length */
1482 ulint rec_len;
1483
1484 /** default column value if any */
1485 byte *default_rec;
1486 };
1487
1488 /** The dirty status of tables, used to indicate if a table has some
1489 dynamic metadata changed to be written back */
1490 enum table_dirty_status {
1491 /** Some persistent metadata is now dirty in memory, need to be
1492 written back to DDTableBuffer table and(or directly to) DD table.
1493 There could be some exceptions, when it's marked as dirty, but
1494 the metadata has already been written back to DDTableBuffer.
1495 For example, if a corrupted index is found and marked as corrupted,
1496 then it gets dropped. At this time, the dirty_status is still of
1497 this dirty value. Also a concurrent checkpoint make this bit
1498 out-of-date for other working threads, which still think the
1499 status is dirty and write-back is necessary.
1500 There could be either one row or no row for this table in
1501 DDTableBuffer table */
1502 METADATA_DIRTY = 0,
1503 /** Some persistent metadata is buffered in DDTableBuffer table,
1504 need to be written back to DD table. There is must be one row in
1505 DDTableBuffer table for this table */
1506 METADATA_BUFFERED,
1507 /** All persistent metadata are up to date. There is no row
1508 for this table in DDTableBuffer table */
1509 METADATA_CLEAN
1510 };
1511
1512 #ifndef UNIV_HOTBACKUP
1513 /** A vector to collect prebuilt from different readers working on the same
1514 temp table */
1515 typedef std::vector<row_prebuilt_t *> temp_prebuilt_vec;
1516 #endif /* !UNIV_HOTBACKUP */
1517
1518 /** Data structure for a database table. Most fields will be
1519 initialized to 0, NULL or FALSE in dict_mem_table_create(). */
1520 struct dict_table_t {
1521 /** Check if the table is compressed.
1522 @return true if compressed, false otherwise. */
is_compresseddict_table_t1523 bool is_compressed() const { return (DICT_TF_GET_ZIP_SSIZE(flags) != 0); }
1524
1525 /** Get reference count.
1526 @return current value of n_ref_count */
1527 inline uint64_t get_ref_count() const;
1528
1529 /** Acquire the table handle. */
1530 inline void acquire();
1531
1532 /** Acquire the table handle, with lock() and unlock() the table.
1533 This function needs to be called for opening table when the table
1534 is in memory and later the stats information would be initialized */
1535 inline void acquire_with_lock();
1536
1537 /** Release the table handle. */
1538 inline void release();
1539
1540 /** Lock the table handle. */
1541 inline void lock();
1542
1543 /** Unlock the table handle. */
1544 inline void unlock();
1545
1546 #ifndef UNIV_HOTBACKUP
1547 /** Get schema and table name in system character set.
1548 @param[out] schema schema name
1549 @param[out] table table name */
1550 void get_table_name(std::string &schema, std::string &table);
1551
1552 /** Mutex of the table for concurrency access. */
1553 ib_mutex_t *mutex;
1554
1555 /** Creation state of mutex. */
1556 volatile os_once::state_t mutex_created;
1557 #endif /* !UNIV_HOTBACKUP */
1558
1559 /** Id of the table. */
1560 table_id_t id;
1561
1562 /** Memory heap. If you allocate from this heap after the table has
1563 been created then be sure to account the allocation into
1564 dict_sys->size. When closing the table we do something like
1565 dict_sys->size -= mem_heap_get_size(table->heap) and if that is going
1566 to become negative then we would assert. Something like this should do:
1567 old_size = mem_heap_get_size()
1568 mem_heap_alloc()
1569 new_size = mem_heap_get_size()
1570 dict_sys->size += new_size - old_size. */
1571 mem_heap_t *heap;
1572
1573 /** Table name. */
1574 table_name_t name;
1575
1576 /** Truncate name. */
1577 table_name_t trunc_name;
1578
1579 /** NULL or the directory path specified by DATA DIRECTORY. */
1580 char *data_dir_path;
1581
1582 /** NULL or the tablespace name that this table is assigned to,
1583 specified by the TABLESPACE option.*/
1584 id_name_t tablespace;
1585
1586 /** Space where the clustered index of the table is placed. */
1587 space_id_t space;
1588
1589 /** dd::Tablespace::id of the table */
1590 dd::Object_id dd_space_id;
1591
1592 /** Stores information about:
1593 1 row format (redundant or compact),
1594 2 compressed page size (zip shift size),
1595 3 whether using atomic blobs,
1596 4 whether the table has been created with the option DATA DIRECTORY.
1597 Use DICT_TF_GET_COMPACT(), DICT_TF_GET_ZIP_SSIZE(),
1598 DICT_TF_HAS_ATOMIC_BLOBS() and DICT_TF_HAS_DATA_DIR() to parse this
1599 flag. */
1600 unsigned flags : DICT_TF_BITS;
1601
1602 /** Stores information about:
1603 1 whether the table has been created using CREATE TEMPORARY TABLE,
1604 2 whether the table has an internally defined DOC ID column,
1605 3 whether the table has a FTS index,
1606 4 whether DOC ID column need to be added to the FTS index,
1607 5 whether the table is being created its own tablespace,
1608 6 whether the table has been DISCARDed,
1609 7 whether the aux FTS tables names are in hex.
1610 8 whether the table is instinc table.
1611 9 whether the table has encryption setting.
1612 Use DICT_TF2_FLAG_IS_SET() to parse this flag. */
1613 unsigned flags2 : DICT_TF2_BITS;
1614
1615 /** TRUE if the table is an intermediate table during copy alter
1616 operation or a partition/subpartition which is required for copying
1617 data and skip the undo log for insertion of row in the table.
1618 This variable will be set and unset during extra(), or during the
1619 process of altering partitions */
1620 unsigned skip_alter_undo : 1;
1621
1622 /** TRUE if this is in a single-table tablespace and the .ibd file is
1623 missing. Then we must return in ha_innodb.cc an error if the user
1624 tries to query such an orphaned table. */
1625 unsigned ibd_file_missing : 1;
1626
1627 /** TRUE if the table object has been added to the dictionary cache. */
1628 unsigned cached : 1;
1629
1630 /** TRUE if the table is to be dropped, but not yet actually dropped
1631 (could in the background drop list). It is turned on at the beginning
1632 of row_drop_table_for_mysql() and turned off just before we start to
1633 update system tables for the drop. It is protected by
1634 dict_operation_lock. */
1635 unsigned to_be_dropped : 1;
1636
1637 /** Number of non-virtual columns defined so far. */
1638 unsigned n_def : 10;
1639
1640 /** Number of non-virtual columns. */
1641 unsigned n_cols : 10;
1642
1643 /** Number of non-virtual columns before first instant ADD COLUMN,
1644 including the system columns like n_cols. */
1645 unsigned n_instant_cols : 10;
1646
1647 /** Number of total columns (inlcude virtual and non-virtual) */
1648 unsigned n_t_cols : 10;
1649
1650 /** Number of total columns defined so far. */
1651 unsigned n_t_def : 10;
1652
1653 /** Number of virtual columns defined so far. */
1654 unsigned n_v_def : 10;
1655
1656 /** Number of virtual columns. */
1657 unsigned n_v_cols : 10;
1658
1659 /** Number of multi-value virtual columns. */
1660 unsigned n_m_v_cols : 10;
1661
1662 /** TRUE if this table is expected to be kept in memory. This table
1663 could be a table that has FK relationships or is undergoing DDL */
1664 unsigned can_be_evicted : 1;
1665
1666 /** TRUE if this table is not evictable(can_be_evicted) and this is
1667 because of DDL operation */
1668 unsigned ddl_not_evictable : 1;
1669
1670 /** TRUE if some indexes should be dropped after ONLINE_INDEX_ABORTED
1671 or ONLINE_INDEX_ABORTED_DROPPED. */
1672 unsigned drop_aborted : 1;
1673
1674 /** Array of column descriptions. */
1675 dict_col_t *cols;
1676
1677 /** Array of virtual column descriptions. */
1678 dict_v_col_t *v_cols;
1679
1680 /** List of stored column descriptions. It is used only for foreign key
1681 check during create table and copy alter operations.
1682 During copy alter, s_cols list is filled during create table operation
1683 and need to preserve till rename table operation. That is the
1684 reason s_cols is a part of dict_table_t */
1685 dict_s_col_list *s_cols;
1686
1687 /** Column names packed in a character string
1688 "name1\0name2\0...nameN\0". Until the string contains n_cols, it will
1689 be allocated from a temporary heap. The final string will be allocated
1690 from table->heap. */
1691 const char *col_names;
1692
1693 /** Virtual column names */
1694 const char *v_col_names;
1695
1696 /** True if the table belongs to a system database (mysql, information_schema
1697 or performance_schema) */
1698 bool is_system_table;
1699
1700 /** Hash chain node. */
1701 hash_node_t name_hash;
1702
1703 /** Hash chain node. */
1704 hash_node_t id_hash;
1705
1706 /** The FTS_DOC_ID_INDEX, or NULL if no fulltext indexes exist */
1707 dict_index_t *fts_doc_id_index;
1708
1709 /** List of indexes of the table. */
1710 UT_LIST_BASE_NODE_T(dict_index_t) indexes;
1711
1712 /** List of foreign key constraints in the table. These refer to
1713 columns in other tables. */
1714 UT_LIST_BASE_NODE_T(dict_foreign_t) foreign_list;
1715
1716 /** List of foreign key constraints which refer to this table. */
1717 UT_LIST_BASE_NODE_T(dict_foreign_t) referenced_list;
1718
1719 /** Node of the LRU list of tables. */
1720 UT_LIST_NODE_T(dict_table_t) table_LRU;
1721
1722 /** metadata version number of dd::Table::se_private_data() */
1723 uint64_t version;
1724
1725 /** table dynamic metadata status, protected by dict_persist->mutex */
1726 std::atomic<table_dirty_status> dirty_status;
1727
1728 #ifndef UNIV_HOTBACKUP
1729 /** Node of the dirty table list of tables, which is protected
1730 by dict_persist->mutex */
1731 UT_LIST_NODE_T(dict_table_t) dirty_dict_tables;
1732 #endif /* !UNIV_HOTBACKUP */
1733
1734 #ifdef UNIV_DEBUG
1735 /** This field is used to mark if a table is in the
1736 dirty_dict_tables_list. if the dirty_status is not of
1737 METADATA_CLEAN, the table should be in the list, otherwise not.
1738 This field should be protected by dict_persist->mutex too. */
1739 bool in_dirty_dict_tables_list;
1740 #endif /* UNIV_DEBUG */
1741
1742 /** Maximum recursive level we support when loading tables chained
1743 together with FK constraints. If exceeds this level, we will stop
1744 loading child table into memory along with its parent table. */
1745 unsigned fk_max_recusive_level : 8;
1746
1747 /** Count of how many foreign key check operations are currently being
1748 performed on the table. We cannot drop the table while there are
1749 foreign key checks running on it. */
1750 ulint n_foreign_key_checks_running;
1751
1752 /** Transaction id that last touched the table definition. Either when
1753 loading the definition or CREATE TABLE, or ALTER TABLE (prepare,
1754 commit, and rollback phases). */
1755 trx_id_t def_trx_id;
1756
1757 /*!< set of foreign key constraints in the table; these refer to
1758 columns in other tables */
1759 dict_foreign_set foreign_set;
1760
1761 /*!< set of foreign key constraints which refer to this table */
1762 dict_foreign_set referenced_set;
1763
1764 #ifdef UNIV_DEBUG
1765 /** This field is used to specify in simulations tables which are so
1766 big that disk should be accessed. Disk access is simulated by putting
1767 the thread to sleep for a while. NOTE that this flag is not stored to
1768 the data dictionary on disk, and the database will forget about value
1769 TRUE if it has to reload the table definition from disk. */
1770 ibool does_not_fit_in_memory;
1771 #endif /* UNIV_DEBUG */
1772
1773 /** TRUE if the maximum length of a single row exceeds BIG_ROW_SIZE.
1774 Initialized in dict_table_add_to_cache(). */
1775 unsigned big_rows : 1;
1776
1777 #ifndef UNIV_HOTBACKUP
1778 /** Statistics for query optimization. @{ */
1779
1780 /** Creation state of 'stats_latch'. */
1781 volatile os_once::state_t stats_latch_created;
1782
1783 /** This latch protects:
1784 "dict_table_t::stat_initialized",
1785 "dict_table_t::stat_n_rows (*)",
1786 "dict_table_t::stat_clustered_index_size",
1787 "dict_table_t::stat_sum_of_other_index_sizes",
1788 "dict_table_t::stat_modified_counter (*)",
1789 "dict_table_t::indexes*::stat_n_diff_key_vals[]",
1790 "dict_table_t::indexes*::stat_index_size",
1791 "dict_table_t::indexes*::stat_n_leaf_pages".
1792 (*) Those are not always protected for
1793 performance reasons. */
1794 rw_lock_t *stats_latch;
1795
1796 /** TRUE if statistics have been calculated the first time after
1797 database startup or table creation. */
1798 unsigned stat_initialized : 1;
1799
1800 /** Timestamp of last recalc of the stats. */
1801 ib_time_monotonic_t stats_last_recalc;
1802
1803 /** The two bits below are set in the 'stat_persistent' member. They
1804 have the following meaning:
1805 1. _ON=0, _OFF=0, no explicit persistent stats setting for this table,
1806 the value of the global srv_stats_persistent is used to determine
1807 whether the table has persistent stats enabled or not
1808 2. _ON=0, _OFF=1, persistent stats are explicitly disabled for this
1809 table, regardless of the value of the global srv_stats_persistent
1810 3. _ON=1, _OFF=0, persistent stats are explicitly enabled for this
1811 table, regardless of the value of the global srv_stats_persistent
1812 4. _ON=1, _OFF=1, not allowed, we assert if this ever happens. */
1813 #define DICT_STATS_PERSISTENT_ON (1 << 1)
1814 #define DICT_STATS_PERSISTENT_OFF (1 << 2)
1815
1816 /** Indicates whether the table uses persistent stats or not. See
1817 DICT_STATS_PERSISTENT_ON and DICT_STATS_PERSISTENT_OFF. */
1818 ib_uint32_t stat_persistent;
1819
1820 /** The two bits below are set in the 'stats_auto_recalc' member. They
1821 have the following meaning:
1822 1. _ON=0, _OFF=0, no explicit auto recalc setting for this table, the
1823 value of the global srv_stats_persistent_auto_recalc is used to
1824 determine whether the table has auto recalc enabled or not
1825 2. _ON=0, _OFF=1, auto recalc is explicitly disabled for this table,
1826 regardless of the value of the global srv_stats_persistent_auto_recalc
1827 3. _ON=1, _OFF=0, auto recalc is explicitly enabled for this table,
1828 regardless of the value of the global srv_stats_persistent_auto_recalc
1829 4. _ON=1, _OFF=1, not allowed, we assert if this ever happens. */
1830 #define DICT_STATS_AUTO_RECALC_ON (1 << 1)
1831 #define DICT_STATS_AUTO_RECALC_OFF (1 << 2)
1832
1833 /** Indicates whether the table uses automatic recalc for persistent
1834 stats or not. See DICT_STATS_AUTO_RECALC_ON and
1835 DICT_STATS_AUTO_RECALC_OFF. */
1836 ib_uint32_t stats_auto_recalc;
1837
1838 /** The number of pages to sample for this table during persistent
1839 stats estimation. If this is 0, then the value of the global
1840 srv_stats_persistent_sample_pages will be used instead. */
1841 ulint stats_sample_pages;
1842
1843 /** Approximate number of rows in the table. We periodically calculate
1844 new estimates. */
1845 ib_uint64_t stat_n_rows;
1846
1847 /** Approximate clustered index size in database pages. */
1848 ulint stat_clustered_index_size;
1849
1850 /** Approximate size of other indexes in database pages. */
1851 ulint stat_sum_of_other_index_sizes;
1852
1853 /** If FTS AUX table, parent table id */
1854 table_id_t parent_id;
1855
1856 /** How many rows are modified since last stats recalc. When a row is
1857 inserted, updated, or deleted, we add 1 to this number; we calculate
1858 new estimates for the table and the indexes if the table has changed
1859 too much, see row_update_statistics_if_needed(). The counter is reset
1860 to zero at statistics calculation. This counter is not protected by
1861 any latch, because this is only used for heuristics. */
1862 ib_uint64_t stat_modified_counter;
1863
1864 /** Background stats thread is not working on this table. */
1865 #define BG_STAT_NONE 0
1866
1867 /** Set in 'stats_bg_flag' when the background stats code is working
1868 on this table. The DROP TABLE code waits for this to be cleared before
1869 proceeding. */
1870 #define BG_STAT_IN_PROGRESS (1 << 0)
1871
1872 /** Set in 'stats_bg_flag' when DROP TABLE starts waiting on
1873 BG_STAT_IN_PROGRESS to be cleared. The background stats thread will
1874 detect this and will eventually quit sooner. */
1875 #define BG_STAT_SHOULD_QUIT (1 << 1)
1876
1877 /** The state of the background stats thread wrt this table.
1878 See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT.
1879 Writes are covered by dict_sys->mutex. Dirty reads are possible. */
1880 byte stats_bg_flag;
1881
1882 /* @} */
1883 #endif /* !UNIV_HOTBACKUP */
1884
1885 /** AUTOINC related members. @{ */
1886
1887 /* The actual collection of tables locked during AUTOINC read/write is
1888 kept in trx_t. In order to quickly determine whether a transaction has
1889 locked the AUTOINC lock we keep a pointer to the transaction here in
1890 the 'autoinc_trx' member. This is to avoid acquiring lock_sys latches and
1891 scanning the vector in trx_t.
1892 When an AUTOINC lock has to wait, the corresponding lock instance is
1893 created on the trx lock heap rather than use the pre-allocated instance
1894 in autoinc_lock below. */
1895
1896 /** A buffer for an AUTOINC lock for this table. We allocate the
1897 memory here so that individual transactions can get it and release it
1898 without a need to allocate space from the lock heap of the trx:
1899 otherwise the lock heap would grow rapidly if we do a large insert
1900 from a select. */
1901 #ifndef UNIV_HOTBACKUP
1902 lock_t *autoinc_lock;
1903
1904 /** Creation state of autoinc_mutex member */
1905 volatile os_once::state_t autoinc_mutex_created;
1906 #endif /* !UNIV_HOTBACKUP */
1907
1908 /** Mutex protecting the autoincrement counter. */
1909 ib_mutex_t *autoinc_mutex;
1910
1911 /** Autoinc counter value to give to the next inserted row. */
1912 ib_uint64_t autoinc;
1913
1914 /** Mutex protecting the persisted autoincrement counter. */
1915 ib_mutex_t *autoinc_persisted_mutex;
1916
1917 /** Autoinc counter value that has been persisted in redo logs or
1918 DDTableBuffer. It's mainly used when we want to write counter back
1919 to DDTableBuffer.
1920 This is different from the 'autoinc' above, which could be bigger
1921 than this one, because 'autoinc' will get updated right after
1922 some counters are allocated, but we will write the counter to redo
1923 logs and update this counter later. Once all allocated counters
1924 have been written to redo logs, 'autoinc' should be exact the next
1925 counter of this persisted one.
1926 We want this counter because when we need to write the counter back
1927 to DDTableBuffer, we had better keep it consistency with the counter
1928 that has been written to redo logs. Besides, we can't read the 'autoinc'
1929 directly easily, because the autoinc_lock is required and there could
1930 be a deadlock.
1931 This variable is protected by autoinc_persisted_mutex. */
1932 ib_uint64_t autoinc_persisted;
1933
1934 /** The position of autoinc counter field in clustered index. This would
1935 be set when CREATE/ALTER/OPEN TABLE and IMPORT TABLESPACE, and used in
1936 modifications to clustered index, such as INSERT/UPDATE. There should
1937 be no conflict to access it, so no protection is needed. */
1938 ulint autoinc_field_no;
1939
1940 /** The transaction that currently holds the the AUTOINC lock on this table.
1941 Protected by lock_sys table shard latch. To "peek" the current value one
1942 can read it without any latch, understanding that in general it may change.
1943 Such access pattern is correct if trx thread wants to check if it has the lock
1944 granted, as the field can only change to other value when lock is released,
1945 which can not happen concurrently to thread executing the trx. */
1946 std::atomic<const trx_t *> autoinc_trx;
1947
1948 /* @} */
1949
1950 #ifndef UNIV_HOTBACKUP
1951 /** FTS specific state variables. */
1952 fts_t *fts;
1953 #endif /* !UNIV_HOTBACKUP */
1954
1955 /** Quiescing states, protected by the dict_index_t::lock. ie. we can
1956 only change the state if we acquire all the latches (dict_index_t::lock)
1957 in X mode of this table's indexes. */
1958 ib_quiesce_t quiesce;
1959
1960 /** Count of the number of record locks on this table. We use this to
1961 determine whether we can evict the table from the dictionary cache.
1962 Writes (atomic increments and decrements) are performed when holding a shared
1963 latch on lock_sys. (Note that this the table's shard latch is NOT required,
1964 as this is field counts *record* locks, so a page shard is latched instead)
1965 Reads should be performed when holding exclusive lock_sys latch, however:
1966 - Some places assert this field is zero without holding any latch.
1967 - Some places assert this field is positive holding only shared latch. */
1968 std::atomic<size_t> n_rec_locks;
1969
1970 #ifndef UNIV_DEBUG
1971 private:
1972 #endif
1973 /** Count of how many handles are opened to this table. Dropping of the
1974 table is NOT allowed until this count gets to zero. MySQL does NOT
1975 itself check the number of open handles at DROP. */
1976 std::atomic<uint64_t> n_ref_count;
1977
1978 public:
1979 #ifndef UNIV_HOTBACKUP
1980 /** List of locks on the table. Protected by lock_sys shard latch. */
1981 table_lock_list_t locks;
1982 /** count_by_mode[M] = number of locks in this->locks with
1983 lock->type_mode&LOCK_MODE_MASK == M.
1984 Used to quickly verify that there are no LOCK_S or LOCK_X, which are the only
1985 modes incompatible with LOCK_IS and LOCK_IX, to avoid costly iteration over
1986 this->locks when adding LOCK_IS or LOCK_IX.
1987 We use count_by_mode[LOCK_AUTO_INC] to track the number of granted and pending
1988 autoinc locks on this table. This value is set after acquiring the lock_sys
1989 table shard latch, but we peek the contents to determine whether other
1990 transactions have acquired the AUTOINC lock or not. Of course only one
1991 transaction can be granted the lock but there can be multiple
1992 waiters.
1993 Protected by lock_sys table shard latch. */
1994 ulong count_by_mode[LOCK_NUM];
1995 #endif /* !UNIV_HOTBACKUP */
1996
1997 /** Timestamp of the last modification of this table. */
1998 time_t update_time;
1999
2000 /** row-id counter for use by intrinsic table for getting row-id.
2001 Given intrinsic table semantics, row-id can be locally maintained
2002 instead of getting it from central generator which involves mutex
2003 locking. */
2004 ib_uint64_t sess_row_id;
2005
2006 /** trx_id counter for use by intrinsic table for getting trx-id.
2007 Intrinsic table are not shared so don't need a central trx-id
2008 but just need a increased counter to track consistent view while
2009 proceeding SELECT as part of UPDATE. */
2010 ib_uint64_t sess_trx_id;
2011
2012 #ifdef UNIV_DEBUG
2013 /** Value of 'magic_n'. */
2014 #define DICT_TABLE_MAGIC_N 76333786
2015
2016 /** Magic number. */
2017 ulint magic_n;
2018 #endif /* UNIV_DEBUG */
2019 /** mysql_row_templ_t for base columns used for compute the virtual
2020 columns */
2021 dict_vcol_templ_t *vc_templ;
2022
2023 /** encryption key, it's only for export/import */
2024 byte *encryption_key;
2025
2026 /** encryption iv, it's only for export/import */
2027 byte *encryption_iv;
2028
2029 /** remove the dict_table_t from cache after DDL operation */
2030 bool discard_after_ddl;
2031
2032 /** refresh/reload FK info */
2033 bool refresh_fk;
2034
2035 #ifndef UNIV_HOTBACKUP
2036 /** multiple cursors can be active on this temporary table */
2037 temp_prebuilt_vec *temp_prebuilt;
2038 #endif /* !UNIV_HOTBACKUP */
2039
2040 /** TRUE only for dictionary tables like mysql/tables,
2041 mysql/columns, mysql/tablespaces, etc. This flag is used
2042 to do non-locking reads on DD tables. */
2043 bool is_dd_table;
2044
2045 /** true if this table is explicitly put to non-LRU list
2046 during table creation */
2047 bool explicitly_non_lru;
2048
2049 /** @return the clustered index */
first_indexdict_table_t2050 const dict_index_t *first_index() const {
2051 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2052 const dict_index_t *first = UT_LIST_GET_FIRST(indexes);
2053 return (first);
2054 }
2055 /** @return the clustered index */
first_indexdict_table_t2056 dict_index_t *first_index() {
2057 return (const_cast<dict_index_t *>(
2058 const_cast<const dict_table_t *>(this)->first_index()));
2059 }
2060
2061 /** @return if there was any instantly added column.
2062 This will be true after one or more instant ADD COLUMN, however,
2063 it would become false after ALTER TABLE which rebuilds or copies
2064 the old table.
2065 If this is true, all instantly added columns should have default
2066 values, and records in the table may have REC_INFO_INSTANT_FLAG set. */
has_instant_colsdict_table_t2067 bool has_instant_cols() const {
2068 ut_ad(n_instant_cols <= n_cols);
2069
2070 return (n_instant_cols < n_cols);
2071 }
2072
2073 /** Set the number of columns when the first instant ADD COLUMN happens.
2074 @param[in] instant_cols number of fields when first instant
2075 ADD COLUMN happens, without system
2076 columns */
set_instant_colsdict_table_t2077 void set_instant_cols(uint16_t instant_cols) {
2078 n_instant_cols = static_cast<unsigned>(instant_cols) + get_n_sys_cols();
2079 }
2080
2081 /** Get the number of user columns when the first instant ADD COLUMN
2082 happens.
2083 @return the number of user columns as described above */
get_instant_colsdict_table_t2084 uint16_t get_instant_cols() const {
2085 return static_cast<uint16_t>(n_instant_cols - get_n_sys_cols());
2086 }
2087
2088 /** Check whether the table is corrupted.
2089 @return true if the table is corrupted, otherwise false */
is_corrupteddict_table_t2090 bool is_corrupted() const {
2091 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2092
2093 const dict_index_t *index = first_index();
2094
2095 /* It is possible that this table is only half created, in which case
2096 the clustered index may be NULL. If the clustered index is corrupted,
2097 the table is corrupt. We do not consider the table corrupt if only
2098 a secondary index is corrupt. */
2099 ut_ad(index == nullptr || index->is_clustered());
2100
2101 return (index != nullptr && index->type & DICT_CORRUPT);
2102 }
2103
2104 /** Returns a column's name.
2105 @param[in] col_nr column number
2106 @return column name. NOTE: not guaranteed to stay valid if table is
2107 modified in any way (columns added, etc.). */
get_col_namedict_table_t2108 const char *get_col_name(ulint col_nr) const {
2109 ut_ad(col_nr < n_def);
2110 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2111
2112 const char *s = col_names;
2113 if (s) {
2114 for (ulint i = 0; i < col_nr; i++) {
2115 s += strlen(s) + 1;
2116 }
2117 }
2118
2119 return (s);
2120 }
2121
field_numberdict_table_t2122 int field_number(const char *field_name) const {
2123 for (int i = 0; i < n_def; ++i) {
2124 if (strcmp(field_name, get_col_name(i)) == 0) {
2125 return i;
2126 }
2127 }
2128 ut_a(0);
2129 }
2130
2131 /**Gets the nth column of a table.
2132 @param[in] pos position of column
2133 @return pointer to column object */
get_coldict_table_t2134 dict_col_t *get_col(ulint pos) const {
2135 ut_ad(pos < n_def);
2136 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2137
2138 return (cols + pos);
2139 }
2140
2141 /** Gets the number of user-defined non-virtual columns in a table
2142 in the dictionary cache.
2143 @return number of user-defined (e.g., not ROW_ID) non-virtual columns
2144 of a table */
get_n_user_colsdict_table_t2145 uint16_t get_n_user_cols() const {
2146 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2147
2148 return (static_cast<uint16_t>(n_cols) - get_n_sys_cols());
2149 }
2150
2151 /** Gets the number of system columns in a table.
2152 For intrinsic table on ROW_ID column is added for all other
2153 tables TRX_ID and ROLL_PTR are all also appeneded.
2154 @return number of system (e.g., ROW_ID) columns of a table */
get_n_sys_colsdict_table_t2155 uint16_t get_n_sys_cols() const {
2156 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2157
2158 return (is_intrinsic() ? DATA_ITT_N_SYS_COLS : DATA_N_SYS_COLS);
2159 }
2160
2161 /** Gets the number of all non-virtual columns (also system) in a table
2162 in the dictionary cache.
2163 @return number of non-virtual columns of a table */
get_n_colsdict_table_t2164 ulint get_n_cols() const {
2165 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2166
2167 return (n_cols);
2168 }
2169
2170 /** Gets the given system column of a table.
2171 @param[in] sys DATA_ROW_ID, ...
2172 @return pointer to column object */
get_sys_coldict_table_t2173 dict_col_t *get_sys_col(ulint sys) const {
2174 dict_col_t *col;
2175
2176 ut_ad(sys < get_n_sys_cols());
2177 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2178
2179 col = get_col(n_cols - get_n_sys_cols() + sys);
2180 ut_ad(col->mtype == DATA_SYS);
2181 ut_ad(col->prtype == (sys | DATA_NOT_NULL));
2182
2183 return (col);
2184 }
2185
2186 /** Determine if this is a temporary table. */
is_temporarydict_table_t2187 bool is_temporary() const {
2188 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2189 return (flags2 & DICT_TF2_TEMPORARY);
2190 }
2191
2192 /** Determine if this is a FTS AUX table. */
is_fts_auxdict_table_t2193 bool is_fts_aux() const {
2194 ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2195 return (flags2 & DICT_TF2_AUX);
2196 }
2197
2198 /** Determine whether the table is intrinsic.
2199 An intrinsic table is a special kind of temporary table that
2200 is invisible to the end user. It can be created internally by InnoDB,
2201 the MySQL server layer or other modules connected to InnoDB in order
2202 to gather and use data as part of a larger task. Since access to it
2203 must be as fast as possible, it does not need UNDO semantics, system
2204 fields DB_TRX_ID & DB_ROLL_PTR, doublewrite, checksum, insert buffer,
2205 use of the shared data dictionary, locking, or even a transaction.
2206 In short, these are not ACID tables at all, just temporary data stored
2207 and manipulated during a larger process.*/
is_intrinsicdict_table_t2208 bool is_intrinsic() const {
2209 if (flags2 & DICT_TF2_INTRINSIC) {
2210 ut_ad(is_temporary());
2211 return (true);
2212 }
2213
2214 return (false);
2215 }
2216
2217 /* GAP locks are skipped for DD tables and SDI tables
2218 @return true if table is DD table or SDI table, else false */
2219 inline bool skip_gap_locks() const;
2220
2221 /** Determine if the table can support instant ADD COLUMN */
2222 inline bool support_instant_add() const;
2223 };
2224
is_compressed()2225 inline bool dict_index_t::is_compressed() const {
2226 return (table->is_compressed());
2227 }
2228
2229 /** Persistent dynamic metadata type, there should be 1 to 1
2230 relationship between the metadata and the type. Please keep them in order
2231 so that we can iterate over it */
2232 enum persistent_type_t {
2233 /** The smallest type, which should be 1 less than the first
2234 true type */
2235 PM_SMALLEST_TYPE = 0,
2236
2237 /** Persistent Metadata type for corrupted indexes */
2238 PM_INDEX_CORRUPTED = 1,
2239
2240 /** Persistent Metadata type for autoinc counter */
2241 PM_TABLE_AUTO_INC = 2,
2242
2243 /* TODO: Will add following types
2244 PM_TABLE_UPDATE_TIME = 3,
2245 Maybe something tablespace related
2246 PM_TABLESPACE_SIZE = 4,
2247 PM_TABLESPACE_MAX_TRX_ID = 5, */
2248
2249 /** The biggest type, which should be 1 bigger than the last
2250 true type */
2251 PM_BIGGEST_TYPE = 3
2252 };
2253
2254 typedef std::vector<index_id_t, ut_allocator<index_id_t>> corrupted_ids_t;
2255
2256 /** Persistent dynamic metadata for a table */
2257 class PersistentTableMetadata {
2258 public:
2259 /** Constructor
2260 @param[in] id table id
2261 @param[in] version table dynamic metadata version */
PersistentTableMetadata(table_id_t id,uint64 version)2262 PersistentTableMetadata(table_id_t id, uint64 version)
2263 : m_id(id), m_version(version), m_corrupted_ids(), m_autoinc(0) {}
2264
2265 /** Get the corrupted indexes' IDs
2266 @return the vector of indexes' IDs */
get_corrupted_indexes()2267 const corrupted_ids_t &get_corrupted_indexes() const {
2268 return (m_corrupted_ids);
2269 }
2270
2271 /** Add a corrupted index id and space id
2272 @param[in] id corrupted index id */
add_corrupted_index(const index_id_t id)2273 void add_corrupted_index(const index_id_t id) {
2274 m_corrupted_ids.push_back(id);
2275 }
2276
2277 /** Set the dynamic metadata version.
2278 @param[in] version dynamic metadata version */
set_version(uint64_t version)2279 void set_version(uint64_t version) { m_version = version; }
2280
2281 /** Get the dynamic metadata version */
get_version()2282 uint64_t get_version() const { return (m_version); }
2283
2284 /** Get the table id of the metadata
2285 @return table id */
get_table_id()2286 table_id_t get_table_id() const { return (m_id); }
2287
2288 /** Set the autoinc counter of the table if it's bigger
2289 @param[in] autoinc autoinc counter */
set_autoinc_if_bigger(uint64_t autoinc)2290 void set_autoinc_if_bigger(uint64_t autoinc) {
2291 /* We only set the biggest autoinc counter. Callers don't
2292 guarantee passing a bigger number in. */
2293 if (autoinc > m_autoinc) {
2294 m_autoinc = autoinc;
2295 }
2296 }
2297
2298 /** Set the autoinc counter of the table
2299 @param[in] autoinc autoinc counter */
set_autoinc(uint64_t autoinc)2300 void set_autoinc(uint64_t autoinc) { m_autoinc = autoinc; }
2301
2302 /** Get the autoinc counter of the table
2303 @return the autoinc counter */
get_autoinc()2304 uint64_t get_autoinc() const { return (m_autoinc); }
2305
2306 private:
2307 /** Table ID which this metadata belongs to */
2308 table_id_t m_id;
2309
2310 /** Table dynamic metadata version of the change */
2311 uint64_t m_version;
2312
2313 /** Storing the corrupted indexes' ID if exist, or else empty */
2314 corrupted_ids_t m_corrupted_ids;
2315
2316 /** Autoinc counter of the table */
2317 uint64_t m_autoinc;
2318
2319 /* TODO: We will add update_time, etc. here and APIs accordingly */
2320 };
2321
2322 /** Interface for persistent dynamic table metadata. */
2323 class Persister {
2324 public:
2325 /** Virtual desctructor */
~Persister()2326 virtual ~Persister() {}
2327
2328 /** Write the dynamic metadata of a table, we can pre-calculate
2329 the size by calling get_write_size()
2330 @param[in] metadata persistent data
2331 @param[out] buffer write buffer
2332 @param[in] size size of write buffer, should be
2333 at least get_write_size()
2334 @return the length of bytes written */
2335 virtual ulint write(const PersistentTableMetadata &metadata, byte *buffer,
2336 ulint size) const = 0;
2337
2338 /** Pre-calculate the size of metadata to be written
2339 @param[in] metadata metadata to be written
2340 @return the size of metadata */
2341 virtual ulint get_write_size(
2342 const PersistentTableMetadata &metadata) const = 0;
2343
2344 /** Read the dynamic metadata from buffer, and store them to
2345 metadata object
2346 @param[out] metadata metadata where we store the read data
2347 @param[in] buffer buffer to read
2348 @param[in] size size of buffer
2349 @param[out] corrupt true if we found something wrong in
2350 the buffer except incomplete buffer,
2351 otherwise false
2352 @return the bytes we read from the buffer if the buffer data
2353 is complete and we get everything, 0 if the buffer is incompleted */
2354 virtual ulint read(PersistentTableMetadata &metadata, const byte *buffer,
2355 ulint size, bool *corrupt) const = 0;
2356
2357 /** Write MLOG_TABLE_DYNAMIC_META for persistent dynamic
2358 metadata of table
2359 @param[in] id table id
2360 @param[in] metadata metadata used to write the log
2361 @param[in,out] mtr mini-transaction */
2362 void write_log(table_id_t id, const PersistentTableMetadata &metadata,
2363 mtr_t *mtr) const;
2364 };
2365
2366 /** Persister used for corrupted indexes */
2367 class CorruptedIndexPersister : public Persister {
2368 public:
2369 /** Write the corrupted indexes of a table, we can pre-calculate
2370 the size by calling get_write_size()
2371 @param[in] metadata persistent metadata
2372 @param[out] buffer write buffer
2373 @param[in] size size of write buffer, should be
2374 at least get_write_size()
2375 @return the length of bytes written */
2376 ulint write(const PersistentTableMetadata &metadata, byte *buffer,
2377 ulint size) const;
2378
2379 /** Pre-calculate the size of metadata to be written
2380 @param[in] metadata metadata to be written
2381 @return the size of metadata */
2382 ulint get_write_size(const PersistentTableMetadata &metadata) const;
2383
2384 /** Read the corrupted indexes from buffer, and store them to
2385 metadata object
2386 @param[out] metadata metadata where we store the read data
2387 @param[in] buffer buffer to read
2388 @param[in] size size of buffer
2389 @param[out] corrupt true if we found something wrong in
2390 the buffer except incomplete buffer,
2391 otherwise false
2392 @return the bytes we read from the buffer if the buffer data
2393 is complete and we get everything, 0 if the buffer is incomplete */
2394 ulint read(PersistentTableMetadata &metadata, const byte *buffer, ulint size,
2395 bool *corrupt) const;
2396
2397 private:
2398 /** The length of index_id_t we will write */
2399 static const size_t INDEX_ID_LENGTH = 12;
2400 };
2401
2402 /** Persister used for autoinc counters */
2403 class AutoIncPersister : public Persister {
2404 public:
2405 /** Write the autoinc counter of a table, we can pre-calculate
2406 the size by calling get_write_size()
2407 @param[in] metadata persistent metadata
2408 @param[out] buffer write buffer
2409 @param[in] size size of write buffer, should be
2410 at least get_write_size()
2411 @return the length of bytes written */
2412 ulint write(const PersistentTableMetadata &metadata, byte *buffer,
2413 ulint size) const;
2414
2415 /** Pre-calculate the size of metadata to be written
2416 @param[in] metadata metadata to be written
2417 @return the size of metadata */
get_write_size(const PersistentTableMetadata & metadata)2418 inline ulint get_write_size(const PersistentTableMetadata &metadata) const {
2419 /* We just return the max possible size that would be used
2420 if the counter exists, so we don't calculate every time.
2421 Here we need 1 byte for dynamic metadata type and 11 bytes
2422 for the max possible size of counter. */
2423 return (12);
2424 }
2425
2426 /** Read the autoinc counter from buffer, and store them to
2427 metadata object
2428 @param[out] metadata metadata where we store the read data
2429 @param[in] buffer buffer to read
2430 @param[in] size size of buffer
2431 @param[out] corrupt true if we found something wrong in
2432 the buffer except incomplete buffer,
2433 otherwise false
2434 @return the bytes we read from the buffer if the buffer data
2435 is complete and we get everything, 0 if the buffer is incomplete */
2436 ulint read(PersistentTableMetadata &metadata, const byte *buffer, ulint size,
2437 bool *corrupt) const;
2438 };
2439
2440 /** Container of persisters used in the system. Currently we don't need
2441 to protect this object since we only initialize it at very beginning and
2442 destroy it in the end. During the server running, we only get the persisters */
2443 class Persisters {
2444 typedef std::map<
2445 persistent_type_t, Persister *, std::less<persistent_type_t>,
2446 ut_allocator<std::pair<const persistent_type_t, Persister *>>>
2447 persisters_t;
2448
2449 public:
2450 /** Constructor */
Persisters()2451 Persisters() : m_persisters() {}
2452
2453 /** Destructor */
2454 ~Persisters();
2455
2456 /** Get the persister object with specified type
2457 @param[in] type persister type
2458 @return Persister object required or NULL if not found */
2459 Persister *get(persistent_type_t type) const;
2460
2461 /** Add a specified persister of type, we will allocate the Persister
2462 if there is no such persister exist, otherwise do nothing and return
2463 the existing one
2464 @param[in] type persister type
2465 @return the persister of type */
2466 Persister *add(persistent_type_t type);
2467
2468 /** Remove a specified persister of type, we will free the Persister
2469 @param[in] type persister type */
2470 void remove(persistent_type_t type);
2471
2472 /** Serialize the metadata to a buffer
2473 @param[in] metadata metadata to serialize
2474 @param[out] buffer buffer to store the serialized metadata
2475 @return the length of serialized metadata */
2476 size_t write(PersistentTableMetadata &metadata, byte *buffer);
2477
2478 private:
2479 /** A map to store all persisters needed */
2480 persisters_t m_persisters;
2481 };
2482
2483 #ifndef UNIV_HOTBACKUP
2484 /** Initialise the table lock list. */
2485 void lock_table_lock_list_init(
2486 table_lock_list_t *locks); /*!< List to initialise */
2487
2488 /** A function object to add the foreign key constraint to the referenced set
2489 of the referenced table, if it exists in the dictionary cache. */
2490 struct dict_foreign_add_to_referenced_table {
operatordict_foreign_add_to_referenced_table2491 void operator()(dict_foreign_t *foreign) const {
2492 if (dict_table_t *table = foreign->referenced_table) {
2493 std::pair<dict_foreign_set::iterator, bool> ret =
2494 table->referenced_set.insert(foreign);
2495 ut_a(ret.second);
2496 }
2497 }
2498 };
2499
2500 /** Request for lazy creation of the mutex of a given table.
2501 This function is only called from either single threaded environment
2502 or from a thread that has not shared the table object with other threads.
2503 @param[in,out] table table whose mutex is to be created */
dict_table_mutex_create_lazy(dict_table_t * table)2504 inline void dict_table_mutex_create_lazy(dict_table_t *table) {
2505 table->mutex = nullptr;
2506 table->mutex_created = os_once::NEVER_DONE;
2507 }
2508
2509 /** Destroy the mutex of a given table.
2510 This function is only called from either single threaded environment
2511 or from a thread that has not shared the table object with other threads.
2512 @param[in,out] table table whose mutex is to be created */
dict_table_mutex_destroy(dict_table_t * table)2513 inline void dict_table_mutex_destroy(dict_table_t *table) {
2514 if (table->mutex_created == os_once::DONE) {
2515 if (table->mutex != nullptr) {
2516 mutex_free(table->mutex);
2517 UT_DELETE(table->mutex);
2518 }
2519 }
2520 }
2521
2522 /** Destroy the autoinc latch of the given table.
2523 This function is only called from either single threaded environment
2524 or from a thread that has not shared the table object with other threads.
2525 @param[in,out] table table whose stats latch to destroy */
dict_table_autoinc_destroy(dict_table_t * table)2526 inline void dict_table_autoinc_destroy(dict_table_t *table) {
2527 if (table->autoinc_mutex_created == os_once::DONE) {
2528 if (table->autoinc_mutex != nullptr) {
2529 mutex_free(table->autoinc_mutex);
2530 UT_DELETE(table->autoinc_mutex);
2531 }
2532
2533 if (table->autoinc_persisted_mutex != nullptr) {
2534 mutex_free(table->autoinc_persisted_mutex);
2535 UT_DELETE(table->autoinc_persisted_mutex);
2536 }
2537 }
2538 }
2539
2540 /** Request for lazy creation of the autoinc latch of a given table.
2541 This function is only called from either single threaded environment
2542 or from a thread that has not shared the table object with other threads.
2543 @param[in,out] table table whose autoinc latch is to be created. */
dict_table_autoinc_create_lazy(dict_table_t * table)2544 inline void dict_table_autoinc_create_lazy(dict_table_t *table) {
2545 table->autoinc_mutex = nullptr;
2546 table->autoinc_persisted_mutex = nullptr;
2547 table->autoinc_mutex_created = os_once::NEVER_DONE;
2548 }
2549
2550 /** Request a lazy creation of dict_index_t::zip_pad::mutex.
2551 This function is only called from either single threaded environment
2552 or from a thread that has not shared the table object with other threads.
2553 @param[in,out] index index whose zip_pad mutex is to be created */
dict_index_zip_pad_mutex_create_lazy(dict_index_t * index)2554 inline void dict_index_zip_pad_mutex_create_lazy(dict_index_t *index) {
2555 index->zip_pad.mutex = nullptr;
2556 index->zip_pad.mutex_created = os_once::NEVER_DONE;
2557 }
2558
2559 /** Destroy the zip_pad_mutex of the given index.
2560 This function is only called from either single threaded environment
2561 or from a thread that has not shared the table object with other threads.
2562 @param[in,out] index index whose stats latch to destroy */
dict_index_zip_pad_mutex_destroy(dict_index_t * index)2563 inline void dict_index_zip_pad_mutex_destroy(dict_index_t *index) {
2564 if (index->zip_pad.mutex_created == os_once::DONE &&
2565 index->zip_pad.mutex != nullptr) {
2566 mutex_free(index->zip_pad.mutex);
2567 UT_DELETE(index->zip_pad.mutex);
2568 }
2569 }
2570 #endif /* !UNIV_HOTBACKUP */
2571
2572 /** Release the zip_pad_mutex of a given index.
2573 @param[in,out] index index whose zip_pad_mutex is to be released */
dict_index_zip_pad_unlock(dict_index_t * index)2574 inline void dict_index_zip_pad_unlock(dict_index_t *index) {
2575 #ifndef UNIV_HOTBACKUP
2576 mutex_exit(index->zip_pad.mutex);
2577 #endif /* !UNIV_HOTBACKUP */
2578 }
2579
2580 #ifdef UNIV_DEBUG
2581 /** Check if the current thread owns the autoinc_mutex of a given table.
2582 @param[in] table the autoinc_mutex belongs to this table
2583 @return true, if the current thread owns the autoinc_mutex, false otherwise.*/
dict_table_autoinc_own(const dict_table_t * table)2584 inline bool dict_table_autoinc_own(const dict_table_t *table) {
2585 return (mutex_own(table->autoinc_mutex));
2586 }
2587 #endif /* UNIV_DEBUG */
2588
2589 #include "dict0mem.ic"
2590
2591 #endif /* dict0mem_h */
2592