InnoDB Plugin  1.0
dict0mem.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2015, 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 as published by the Free Software
8 Foundation; version 2 of the License.
9 
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17 
18 *****************************************************************************/
19 
20 /**************************************************/
27 #ifndef dict0mem_h
28 #define dict0mem_h
29 
30 #include "univ.i"
31 #include "dict0types.h"
32 #include "data0type.h"
33 #include "mem0mem.h"
34 #include "row0types.h"
35 #include "rem0types.h"
36 #include "btr0types.h"
37 #ifndef UNIV_HOTBACKUP
38 # include "lock0types.h"
39 # include "que0types.h"
40 # include "sync0rw.h"
41 #endif /* !UNIV_HOTBACKUP */
42 #include "ut0mem.h"
43 #include "ut0lst.h"
44 #include "ut0rnd.h"
45 #include "ut0byte.h"
46 #include "hash0hash.h"
47 #include "trx0types.h"
48 #include "fts0fts.h"
49 #include "os0once.h"
50 #include <set>
51 #include <algorithm>
52 #include <iterator>
53 
54 /* Forward declaration. */
55 struct ib_rbt_t;
56 
59 /* @{ */
60 #define DICT_CLUSTERED 1
61 #define DICT_UNIQUE 2
62 #define DICT_UNIVERSAL 4
64 #define DICT_IBUF 8
65 #define DICT_CORRUPT 16
67 #define DICT_FTS 32 /* FTS index; can't be combined with the
68  other flags */
69 
70 #define DICT_IT_BITS 6
72 /* @} */
73 
74 #if 0 /* not implemented, retained for history */
75 
76 #define DICT_TABLE_ORDINARY 1
77 #define DICT_TABLE_CLUSTER_MEMBER 2
78 #define DICT_TABLE_CLUSTER 3 /* this means that the table is
79  really a cluster definition */
80 #endif
81 
82 /* Table and tablespace flags are generally not used for the Antelope file
83 format except for the low order bit, which is used differently depending on
84 where the flags are stored.
85 
86 ==================== Low order flags bit =========================
87  | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC
88 SYS_TABLES.TYPE | 1 | 1 | 1
89 dict_table_t::flags | 0 | 1 | 1
90 FSP_SPACE_FLAGS | 0 | 0 | 1
91 fil_space_t::flags | 0 | 0 | 1
92 
93 Before the 5.1 plugin, SYS_TABLES.TYPE was always DICT_TABLE_ORDINARY (1)
94 and the tablespace flags field was always 0. In the 5.1 plugin, these fields
95 were repurposed to identify compressed and dynamic row formats.
96 
97 The following types and constants describe the flags found in dict_table_t
98 and SYS_TABLES.TYPE. Similar flags found in fil_space_t and FSP_SPACE_FLAGS
99 are described in fsp0fsp.h. */
100 
101 /* @{ */
103 #define DICT_TF_REDUNDANT 0
105 #define DICT_TF_COMPACT 1
109 #define DICT_N_COLS_COMPACT 0x80000000UL
110 
112 #define DICT_TF_WIDTH_COMPACT 1
114 #define DICT_TF_WIDTH_ZIP_SSIZE 4
115 
120 #define DICT_TF_WIDTH_ATOMIC_BLOBS 1
121 
125 #define DICT_TF_WIDTH_DATA_DIR 1
126 
128 #define DICT_TF_BITS (DICT_TF_WIDTH_COMPACT \
129  + DICT_TF_WIDTH_ZIP_SSIZE \
130  + DICT_TF_WIDTH_ATOMIC_BLOBS \
131  + DICT_TF_WIDTH_DATA_DIR)
132 
134 #define DICT_TF_BIT_MASK (~(~0 << DICT_TF_BITS))
135 
137 #define DICT_TF_POS_COMPACT 0
139 #define DICT_TF_POS_ZIP_SSIZE (DICT_TF_POS_COMPACT \
140  + DICT_TF_WIDTH_COMPACT)
142 #define DICT_TF_POS_ATOMIC_BLOBS (DICT_TF_POS_ZIP_SSIZE \
143  + DICT_TF_WIDTH_ZIP_SSIZE)
145 #define DICT_TF_POS_DATA_DIR (DICT_TF_POS_ATOMIC_BLOBS \
146  + DICT_TF_WIDTH_ATOMIC_BLOBS)
148 #define DICT_TF_POS_UNUSED (DICT_TF_POS_DATA_DIR \
149  + DICT_TF_WIDTH_DATA_DIR)
150 
152 #define DICT_TF_MASK_COMPACT \
153  ((~(~0 << DICT_TF_WIDTH_COMPACT)) \
154  << DICT_TF_POS_COMPACT)
156 #define DICT_TF_MASK_ZIP_SSIZE \
157  ((~(~0 << DICT_TF_WIDTH_ZIP_SSIZE)) \
158  << DICT_TF_POS_ZIP_SSIZE)
160 #define DICT_TF_MASK_ATOMIC_BLOBS \
161  ((~(~0 << DICT_TF_WIDTH_ATOMIC_BLOBS)) \
162  << DICT_TF_POS_ATOMIC_BLOBS)
164 #define DICT_TF_MASK_DATA_DIR \
165  ((~(~0 << DICT_TF_WIDTH_DATA_DIR)) \
166  << DICT_TF_POS_DATA_DIR)
167 
169 #define DICT_TF_GET_COMPACT(flags) \
170  ((flags & DICT_TF_MASK_COMPACT) \
171  >> DICT_TF_POS_COMPACT)
173 #define DICT_TF_GET_ZIP_SSIZE(flags) \
174  ((flags & DICT_TF_MASK_ZIP_SSIZE) \
175  >> DICT_TF_POS_ZIP_SSIZE)
177 #define DICT_TF_HAS_ATOMIC_BLOBS(flags) \
178  ((flags & DICT_TF_MASK_ATOMIC_BLOBS) \
179  >> DICT_TF_POS_ATOMIC_BLOBS)
181 #define DICT_TF_HAS_DATA_DIR(flags) \
182  ((flags & DICT_TF_MASK_DATA_DIR) \
183  >> DICT_TF_POS_DATA_DIR)
185 #define DICT_TF_GET_UNUSED(flags) \
186  (flags >> DICT_TF_POS_UNUSED)
187 /* @} */
188 
196 /* @{ */
198 #define DICT_TF2_BITS 7
199 #define DICT_TF2_BIT_MASK ~(~0 << DICT_TF2_BITS)
200 
202 #define DICT_TF2_TEMPORARY 1
204 #define DICT_TF2_FTS_HAS_DOC_ID 2
206 #define DICT_TF2_FTS 4
207 
209 #define DICT_TF2_FTS_ADD_DOC_ID 8
210 
212 #define DICT_TF2_USE_TABLESPACE 16
213 
215 #define DICT_TF2_DISCARDED 32
216 
219 #define DICT_TF2_FTS_AUX_HEX_NAME 64
220 /* @} */
221 
222 #define DICT_TF2_FLAG_SET(table, flag) \
223  (table->flags2 |= (flag))
224 
225 #define DICT_TF2_FLAG_IS_SET(table, flag) \
226  (table->flags2 & (flag))
227 
228 #define DICT_TF2_FLAG_UNSET(table, flag) \
229  (table->flags2 &= ~(flag))
230 
237 #define DICT_FK_MAX_RECURSIVE_LOAD 20
238 
245 #define FK_MAX_CASCADE_DEL 255
246 
247 /**********************************************************************/
250 UNIV_INTERN
253 /*==================*/
254  const char* name,
255  ulint space,
257  ulint n_cols,
258  ulint flags,
259  ulint flags2);
260 /****************************************************************/
262 UNIV_INTERN
263 void
265 /*================*/
266  dict_table_t* table);
267 /**********************************************************************/
269 UNIV_INTERN
270 void
272 /*===================*/
273  dict_table_t* table,
274  mem_heap_t* heap,
275  const char* name,
276  ulint mtype,
277  ulint prtype,
278  ulint len)
279  __attribute__((nonnull(1)));
280 /**********************************************************************/
282 UNIV_INTERN
283 void
285 /*======================*/
286  dict_table_t* table,
287  unsigned nth_col,
288  const char* from,
289  const char* to)
290  __attribute__((nonnull));
291 /**********************************************************************/
294 UNIV_INTERN
295 void
297 /*========================*/
298  dict_col_t* column,
300  ulint col_pos,
301  ulint mtype,
302  ulint prtype,
303  ulint col_len);
304 /**********************************************************************/
307 UNIV_INLINE
308 void
310 /*=======================*/
311  dict_index_t* index,
312  mem_heap_t* heap,
313  const char* table_name,
314  const char* index_name,
315  ulint space,
318  ulint type,
320  ulint n_fields);
321 /**********************************************************************/
324 UNIV_INTERN
327 /*==================*/
328  const char* table_name,
329  const char* index_name,
330  ulint space,
333  ulint type,
335  ulint n_fields);
336 /**********************************************************************/
340 UNIV_INTERN
341 void
343 /*=====================*/
344  dict_index_t* index,
345  const char* name,
346  ulint prefix_len);
349 /**********************************************************************/
351 UNIV_INTERN
352 void
354 /*================*/
355  dict_index_t* index);
356 /**********************************************************************/
359 UNIV_INTERN
362 /*=========================*/
363 
364 /**********************************************************************/
369 UNIV_INTERN
370 void
372 /*===================================*/
373  dict_foreign_t* foreign,
374  ibool do_alloc);
376 /**********************************************************************/
381 UNIV_INTERN
382 void
384 /*======================================*/
385  dict_foreign_t* foreign,
386  ibool do_alloc);
400 UNIV_INTERN
401 char*
403  mem_heap_t* heap,
404  const char* dbtab,
405  table_id_t id);
406 
409 void
410 dict_mem_init(void);
411 
413 struct dict_col_t{
414  /*----------------------*/
417  /* @{ */
418  unsigned prtype:32;
425  unsigned mtype:8;
427  /* the remaining fields do not affect alphabetical ordering: */
429  unsigned len:16;
438  unsigned mbminmaxlen:5;
443  /*----------------------*/
444  /* End of definitions copied from dtype_t */
445  /* @} */
447  unsigned ind:10;
449  unsigned ord_part:1;
452  unsigned max_prefix:12;
455 };
456 
468 #define DICT_ANTELOPE_MAX_INDEX_COL_LEN REC_ANTELOPE_MAX_INDEX_COL_LEN
469 
475 #define DICT_MAX_FIELD_LEN_BY_FORMAT(table) \
476  ((dict_table_get_format(table) < UNIV_FORMAT_B) \
477  ? (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1) \
478  : REC_VERSION_56_MAX_INDEX_COL_LEN)
479 
480 #define DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags) \
481  ((DICT_TF_HAS_ATOMIC_BLOBS(flags) < UNIV_FORMAT_B) \
482  ? (REC_ANTELOPE_MAX_INDEX_COL_LEN - 1) \
483  : REC_VERSION_56_MAX_INDEX_COL_LEN)
484 
486 #define DICT_MAX_FIXED_COL_LEN DICT_ANTELOPE_MAX_INDEX_COL_LEN
487 
491  const char* name;
492  unsigned prefix_len:12;
500  unsigned fixed_len:10;
503 };
504 
505 /**********************************************************************/
527 #define ZIP_PAD_ROUND_LEN (128)
528 
530 #define ZIP_PAD_SUCCESSFUL_ROUND_LIMIT (5)
531 
533 #define ZIP_PAD_INCR (128)
534 
537 extern ulong zip_failure_threshold_pct;
538 
541 extern ulong zip_pad_max;
542 
546 struct zip_pad_info_t {
549  ulint pad;
550  ulint success;
552  ulint failure;
554  ulint n_rounds;
556  volatile os_once::state_t
559 };
560 
564  index_id_t id;
566  const char* name;
567  const char* table_name;
569 #ifndef UNIV_HOTBACKUP
570  unsigned space:32;
572  unsigned page:32;
573 #endif /* !UNIV_HOTBACKUP */
574  unsigned type:DICT_IT_BITS;
577 #define MAX_KEY_LENGTH_BITS 12
578  unsigned trx_id_offset:MAX_KEY_LENGTH_BITS;
583 #if (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
584 # error (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
585 #endif
586  unsigned n_user_defined_cols:10;
590  unsigned n_uniq:10;
593  unsigned n_def:10;
594  unsigned n_fields:10;
595  unsigned n_nullable:10;
596  unsigned cached:1;
598  unsigned to_be_dropped:1;
601  unsigned online_status:2;
609 #ifndef UNIV_HOTBACKUP
610  UT_LIST_NODE_T(dict_index_t)
611  indexes;
614  row_log_t* online_log;
619  /*----------------------*/
621  /* @{ */
622  ib_uint64_t* stat_n_diff_key_vals;
630  ib_uint64_t* stat_n_sample_sizes;
635  ib_uint64_t* stat_n_non_null_key_vals;
636  /* approximate number of non-null key values
637  for this index, for each column where
638  1 <= n <= dict_get_n_unique(index) (the array
639  is indexed from 0 to n_uniq-1); This
640  is used when innodb_stats_method is
641  "nulls_ignored". */
648  /* @} */
649  rw_lock_t lock;
651  trx_id_t trx_id;
656 #endif /* !UNIV_HOTBACKUP */
657 #ifdef UNIV_BLOB_DEBUG
658  ib_mutex_t blobs_mutex;
660  ib_rbt_t* blobs;
663 #endif /* UNIV_BLOB_DEBUG */
664 #ifdef UNIV_DEBUG
665  ulint magic_n;
667 # define DICT_INDEX_MAGIC_N 76789786
668 #endif
669 };
670 
672 enum online_index_status {
689 };
690 
695  mem_heap_t* heap;
697  char* id;
699  unsigned n_fields:10;
705  unsigned type:6;
707  char* foreign_table_name;
711  const char** foreign_col_names;
713  char* referenced_table_name;
718  const char** referenced_col_names;
726 };
727 
728 std::ostream&
729 operator<< (std::ostream& out, const dict_foreign_t& foreign);
731 struct dict_foreign_print {
732 
733  dict_foreign_print(std::ostream& out)
734  : m_out(out)
735  {}
736 
737  void operator()(const dict_foreign_t* foreign) {
738  m_out << *foreign;
739  }
740 private:
741  std::ostream& m_out;
742 };
743 
748 struct dict_foreign_compare {
749 
750  bool operator()(
751  const dict_foreign_t* lhs,
752  const dict_foreign_t* rhs) const
753  {
754  return(ut_strcmp(lhs->id, rhs->id) < 0);
755  }
756 };
757 
761 
763  : m_index(index)
764  {}
765 
766  bool operator()(const dict_foreign_t* foreign) const
767  {
768  return(foreign->referenced_index == m_index);
769  }
770 
771  const dict_index_t* m_index;
772 };
773 
774 /* A function object to check if the foreign constraint is between different
775 tables. Returns true if foreign key constraint is between different tables,
776 false otherwise. */
778 
779  bool operator()(const dict_foreign_t* foreign) const
780  {
781  return(foreign->foreign_table != foreign->referenced_table);
782  }
783 };
784 
790 
791  dict_foreign_matches_id(const char* id)
792  : m_id(id)
793  {}
794 
795  bool operator()(const dict_foreign_t* foreign) const
796  {
797  if (0 == innobase_strcasecmp(foreign->id, m_id)) {
798  return(true);
799  }
800  if (const char* pos = strchr(foreign->id, '/')) {
801  if (0 == innobase_strcasecmp(m_id, pos + 1)) {
802  return(true);
803  }
804  }
805  return(false);
806  }
807 
808  const char* m_id;
809 };
810 
811 typedef std::set<dict_foreign_t*, dict_foreign_compare> dict_foreign_set;
812 
813 std::ostream&
814 operator<< (std::ostream& out, const dict_foreign_set& fk_set);
815 
820  dict_foreign_not_exists(const dict_foreign_set& obj_)
821  : m_foreigns(obj_)
822  {}
823 
824  /* Return true if the given foreign key is not found */
825  bool operator()(dict_foreign_t* const & foreign) const {
826  return(m_foreigns.find(foreign) == m_foreigns.end());
827  }
828 private:
829  const dict_foreign_set& m_foreigns;
830 };
831 
835 bool
837  const dict_foreign_set& fk_set);
838 
843 bool
845  const dict_table_t& table);
846 
847 /*********************************************************************/
849 inline
850 void
852 /*==============*/
853  dict_foreign_t* foreign)
854 {
855  mem_heap_free(foreign->heap);
856 }
857 
862 struct dict_foreign_set_free {
863 
864  dict_foreign_set_free(const dict_foreign_set& foreign_set)
865  : m_foreign_set(foreign_set)
866  {}
867 
869  {
870  std::for_each(m_foreign_set.begin(),
871  m_foreign_set.end(),
873  }
874 
875  const dict_foreign_set& m_foreign_set;
876 };
877 
880 /* @{ */
881 #define DICT_FOREIGN_ON_DELETE_CASCADE 1
882 #define DICT_FOREIGN_ON_DELETE_SET_NULL 2
883 #define DICT_FOREIGN_ON_UPDATE_CASCADE 4
884 #define DICT_FOREIGN_ON_UPDATE_SET_NULL 8
885 #define DICT_FOREIGN_ON_DELETE_NO_ACTION 16
886 #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32
887 /* @} */
888 
889 /* This flag is for sync SQL DDL and memcached DML.
890 if table->memcached_sync_count == DICT_TABLE_IN_DDL means there's DDL running on
891 the table, DML from memcached will be blocked. */
892 #define DICT_TABLE_IN_DDL -1
893 
896 struct dict_table_t{
897 
899  table_id_t id;
901  char* name;
902  const char* dir_path_of_temp_table;
908  char* data_dir_path;
910  unsigned space:32;
913  unsigned flags:DICT_TF_BITS;
914  unsigned flags2:DICT_TF2_BITS;
915  unsigned ibd_file_missing:1;
920  unsigned cached:1;
922  unsigned to_be_dropped:1;
930  unsigned n_def:10;
931  unsigned n_cols:10;
932  unsigned can_be_evicted:1;
935  unsigned corrupted:1;
937  unsigned drop_aborted:1;
941  dict_col_t* cols;
942  const char* col_names;
948 #ifndef UNIV_HOTBACKUP
949  hash_node_t name_hash;
950  hash_node_t id_hash;
951  UT_LIST_BASE_NODE_T(dict_index_t)
952  indexes;
954  dict_foreign_set foreign_set;
959  dict_foreign_set referenced_set;
963  UT_LIST_NODE_T(dict_table_t)
964  table_LRU;
991 #ifdef UNIV_DEBUG
992  /*----------------------*/
1004 #endif /* UNIV_DEBUG */
1005  /*----------------------*/
1006  unsigned big_rows:1;
1011  /* @{ */
1012 
1027  unsigned stat_initialized:1;
1030 #define DICT_TABLE_IN_USED -1
1040  ib_uint32_t stat_persistent;
1057 #define DICT_STATS_PERSISTENT_ON (1 << 1)
1058 #define DICT_STATS_PERSISTENT_OFF (1 << 2)
1059  ib_uint32_t stats_auto_recalc;
1078 #define DICT_STATS_AUTO_RECALC_ON (1 << 1)
1079 #define DICT_STATS_AUTO_RECALC_OFF (1 << 2)
1086  ib_uint64_t stat_n_rows;
1107 #define BG_STAT_NONE 0
1108 #define BG_STAT_IN_PROGRESS (1 << 0)
1109 
1114 #define BG_STAT_SHOULD_QUIT (1 << 1)
1115 
1124  /* @} */
1125  /*----------------------*/
1140  /* @{ */
1157  ib_uint64_t autoinc;
1172  fts_t* fts; /* FTS specific state variables */
1173  /* @} */
1174  /*----------------------*/
1182  /*----------------------*/
1194  UT_LIST_BASE_NODE_T(lock_t)
1195  locks;
1197 #endif /* !UNIV_HOTBACKUP */
1198 
1199 #ifdef UNIV_DEBUG
1200  ulint magic_n;
1202 # define DICT_TABLE_MAGIC_N 76333786
1203 #endif /* UNIV_DEBUG */
1204 };
1205 
1209  void operator()(dict_foreign_t* foreign) const
1210  {
1211  if (dict_table_t* table = foreign->referenced_table) {
1212  std::pair<dict_foreign_set::iterator, bool> ret
1213  = table->referenced_set.insert(foreign);
1214  ut_a(ret.second);
1215  }
1216  }
1217 };
1218 
1223 inline
1224 void
1226  dict_table_t* table)
1227 {
1228  if (table->autoinc_mutex_created == os_once::DONE
1229  && table->autoinc_mutex != NULL) {
1230  mutex_free(table->autoinc_mutex);
1231  delete table->autoinc_mutex;
1232  }
1233 }
1234 
1238 void
1240  void* table_void);
1241 
1245 void
1247  void* index_void);
1248 
1253 inline
1254 void
1256  dict_table_t* table)
1257 {
1258 #ifdef HAVE_ATOMIC_BUILTINS
1259  table->autoinc_mutex = NULL;
1261 #else /* HAVE_ATOMIC_BUILTINS */
1262  dict_table_autoinc_alloc(table);
1264 #endif /* HAVE_ATOMIC_BUILTINS */
1265 }
1266 
1271 inline
1272 void
1274  dict_index_t* index)
1275 {
1276 #ifdef HAVE_ATOMIC_BUILTINS
1277  index->zip_pad.mutex = NULL;
1279 #else /* HAVE_ATOMIC_BUILTINS */
1280  dict_index_zip_pad_alloc(index);
1282 #endif /* HAVE_ATOMIC_BUILTINS */
1283 }
1284 
1289 inline
1290 void
1292  dict_index_t* index)
1293 {
1294  if (index->zip_pad.mutex_created == os_once::DONE
1295  && index->zip_pad.mutex != NULL) {
1296  os_fast_mutex_free(index->zip_pad.mutex);
1297  delete index->zip_pad.mutex;
1298  }
1299 }
1300 
1303 inline
1304 void
1306  dict_index_t* index)
1307 {
1308  os_fast_mutex_unlock(index->zip_pad.mutex);
1309 }
1310 
1311 #ifdef UNIV_DEBUG
1312 
1315 inline
1316 bool
1318  const dict_table_t* table)
1319 {
1320  return(mutex_own(table->autoinc_mutex));
1321 }
1322 #endif /* UNIV_DEBUG */
1323 
1324 #ifndef UNIV_NONINL
1325 #include "dict0mem.ic"
1326 #endif
1327 
1328 #endif