1 /***************************************************************************** 2 3 Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License along with 22 this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25 *****************************************************************************/ 26 27 /**************************************************//** 28 @file include/dict0load.h 29 Loads to the memory cache database object definitions 30 from dictionary tables 31 32 Created 4/24/1996 Heikki Tuuri 33 *******************************************************/ 34 35 #ifndef dict0load_h 36 #define dict0load_h 37 38 #include "univ.i" 39 #include "dict0types.h" 40 #include "trx0types.h" 41 #include "ut0byte.h" 42 #include "mem0mem.h" 43 #include "btr0types.h" 44 45 /** enum that defines all system table IDs. @see SYSTEM_TABLE_NAME[] */ 46 enum dict_system_id_t { 47 SYS_TABLES = 0, 48 SYS_INDEXES, 49 SYS_COLUMNS, 50 SYS_FIELDS, 51 SYS_FOREIGN, 52 SYS_FOREIGN_COLS, 53 SYS_TABLESPACES, 54 SYS_DATAFILES, 55 56 /* This must be last item. Defines the number of system tables. */ 57 SYS_NUM_SYSTEM_TABLES 58 }; 59 60 /** Status bit for dict_process_sys_tables_rec_and_mtr_commit() */ 61 enum dict_table_info_t { 62 DICT_TABLE_LOAD_FROM_RECORD = 0,/*!< Directly populate a dict_table_t 63 structure with information from 64 a SYS_TABLES record */ 65 DICT_TABLE_LOAD_FROM_CACHE = 1 /*!< Check first whether dict_table_t 66 is in the cache, if so, return it */ 67 }; 68 69 /** Check type for dict_check_tablespaces_and_store_max_id() */ 70 enum dict_check_t { 71 /** No user tablespaces have been opened 72 (no crash recovery, no transactions recovered). */ 73 DICT_CHECK_NONE_LOADED = 0, 74 /** Some user tablespaces may have been opened 75 (no crash recovery; recovered table locks for transactions). */ 76 DICT_CHECK_SOME_LOADED, 77 /** All user tablespaces have been opened (crash recovery). */ 78 DICT_CHECK_ALL_LOADED 79 }; 80 81 /********************************************************************//** 82 In a crash recovery we already have all the tablespace objects created. 83 This function compares the space id information in the InnoDB data dictionary 84 to what we already read with fil_load_single_table_tablespaces(). 85 86 In a normal startup, we create the tablespace objects for every table in 87 InnoDB's data dictionary, if the corresponding .ibd file exists. 88 We also scan the biggest space id, and store it to fil_system. */ 89 UNIV_INTERN 90 void 91 dict_check_tablespaces_and_store_max_id( 92 /*====================================*/ 93 dict_check_t dict_check); /*!< in: how to check */ 94 /********************************************************************//** 95 Finds the first table name in the given database. 96 @return own: table name, NULL if does not exist; the caller must free 97 the memory in the string! */ 98 UNIV_INTERN 99 char* 100 dict_get_first_table_name_in_db( 101 /*============================*/ 102 const char* name); /*!< in: database name which ends to '/' */ 103 104 /********************************************************************//** 105 Loads a table definition from a SYS_TABLES record to dict_table_t. 106 Does not load any columns or indexes. 107 @return error message, or NULL on success */ 108 UNIV_INTERN 109 const char* 110 dict_load_table_low( 111 /*================*/ 112 const char* name, /*!< in: table name */ 113 const rec_t* rec, /*!< in: SYS_TABLES record */ 114 dict_table_t** table); /*!< out,own: table, or NULL */ 115 /********************************************************************//** 116 Loads a table column definition from a SYS_COLUMNS record to 117 dict_table_t. 118 @return error message, or NULL on success */ 119 UNIV_INTERN 120 const char* 121 dict_load_column_low( 122 /*=================*/ 123 dict_table_t* table, /*!< in/out: table, could be NULL 124 if we just populate a dict_column_t 125 struct with information from 126 a SYS_COLUMNS record */ 127 mem_heap_t* heap, /*!< in/out: memory heap 128 for temporary storage */ 129 dict_col_t* column, /*!< out: dict_column_t to fill, 130 or NULL if table != NULL */ 131 table_id_t* table_id, /*!< out: table id */ 132 const char** col_name, /*!< out: column name */ 133 const rec_t* rec); /*!< in: SYS_COLUMNS record */ 134 /********************************************************************//** 135 Loads an index definition from a SYS_INDEXES record to dict_index_t. 136 If allocate=TRUE, we will create a dict_index_t structure and fill it 137 accordingly. If allocated=FALSE, the dict_index_t will be supplied by 138 the caller and filled with information read from the record. @return 139 error message, or NULL on success */ 140 UNIV_INTERN 141 const char* 142 dict_load_index_low( 143 /*================*/ 144 byte* table_id, /*!< in/out: table id (8 bytes), 145 an "in" value if allocate=TRUE 146 and "out" when allocate=FALSE */ 147 const char* table_name, /*!< in: table name */ 148 mem_heap_t* heap, /*!< in/out: temporary memory heap */ 149 const rec_t* rec, /*!< in: SYS_INDEXES record */ 150 ibool allocate, /*!< in: TRUE=allocate *index, 151 FALSE=fill in a pre-allocated 152 *index */ 153 dict_index_t** index); /*!< out,own: index, or NULL */ 154 /********************************************************************//** 155 Loads an index field definition from a SYS_FIELDS record to 156 dict_index_t. 157 @return error message, or NULL on success */ 158 UNIV_INTERN 159 const char* 160 dict_load_field_low( 161 /*================*/ 162 byte* index_id, /*!< in/out: index id (8 bytes) 163 an "in" value if index != NULL 164 and "out" if index == NULL */ 165 dict_index_t* index, /*!< in/out: index, could be NULL 166 if we just populate a dict_field_t 167 struct with information from 168 a SYS_FIELDS record */ 169 dict_field_t* sys_field, /*!< out: dict_field_t to be 170 filled */ 171 ulint* pos, /*!< out: Field position */ 172 byte* last_index_id, /*!< in: last index id */ 173 mem_heap_t* heap, /*!< in/out: memory heap 174 for temporary storage */ 175 const rec_t* rec); /*!< in: SYS_FIELDS record */ 176 /********************************************************************//** 177 Using the table->heap, copy the null-terminated filepath into 178 table->data_dir_path and put a null byte before the extension. 179 This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path. 180 Make this data directory path only if it has not yet been saved. */ 181 UNIV_INTERN 182 void 183 dict_save_data_dir_path( 184 /*====================*/ 185 dict_table_t* table, /*!< in/out: table */ 186 char* filepath); /*!< in: filepath of tablespace */ 187 /*****************************************************************//** 188 Make sure the data_file_name is saved in dict_table_t if needed. Try to 189 read it from the file dictionary first, then from SYS_DATAFILES. */ 190 UNIV_INTERN 191 void 192 dict_get_and_save_data_dir_path( 193 /*============================*/ 194 dict_table_t* table, /*!< in/out: table */ 195 bool dict_mutex_own); /*!< in: true if dict_sys->mutex 196 is owned already */ 197 /********************************************************************//** 198 Loads a table definition and also all its index definitions, and also 199 the cluster definition if the table is a member in a cluster. Also loads 200 all foreign key constraints where the foreign key is in the table or where 201 a foreign key references columns in this table. 202 @return table, NULL if does not exist; if the table is stored in an 203 .ibd file, but the file does not exist, then we set the 204 ibd_file_missing flag TRUE in the table object we return */ 205 UNIV_INTERN 206 dict_table_t* 207 dict_load_table( 208 /*============*/ 209 const char* name, /*!< in: table name in the 210 databasename/tablename format */ 211 ibool cached, /*!< in: TRUE=add to cache, FALSE=do not */ 212 dict_err_ignore_t ignore_err); 213 /*!< in: error to be ignored when loading 214 table and its indexes' definition */ 215 /***********************************************************************//** 216 Loads a table object based on the table id. 217 @return table; NULL if table does not exist */ 218 UNIV_INTERN 219 dict_table_t* 220 dict_load_table_on_id( 221 /*==================*/ 222 table_id_t table_id, /*!< in: table id */ 223 dict_err_ignore_t ignore_err); /*!< in: errors to ignore 224 when loading the table */ 225 /********************************************************************//** 226 This function is called when the database is booted. 227 Loads system table index definitions except for the clustered index which 228 is added to the dictionary cache at booting before calling this function. */ 229 UNIV_INTERN 230 void 231 dict_load_sys_table( 232 /*================*/ 233 dict_table_t* table); /*!< in: system table */ 234 /***********************************************************************//** 235 Loads foreign key constraints where the table is either the foreign key 236 holder or where the table is referenced by a foreign key. Adds these 237 constraints to the data dictionary. Note that we know that the dictionary 238 cache already contains all constraints where the other relevant table is 239 already in the dictionary cache. 240 @return DB_SUCCESS or error code */ 241 UNIV_INTERN 242 dberr_t 243 dict_load_foreigns( 244 /*===============*/ 245 const char* table_name, /*!< in: table name */ 246 const char** col_names, /*!< in: column names, or NULL 247 to use table->col_names */ 248 bool check_recursive,/*!< in: Whether to check 249 recursive load of tables 250 chained by FK */ 251 bool check_charsets, /*!< in: whether to check 252 charset compatibility */ 253 dict_err_ignore_t ignore_err) /*!< in: error to be ignored */ 254 MY_ATTRIBUTE((nonnull(1), warn_unused_result)); 255 /********************************************************************//** 256 Prints to the standard output information on all tables found in the data 257 dictionary system table. */ 258 UNIV_INTERN 259 void 260 dict_print(void); 261 /*============*/ 262 263 /********************************************************************//** 264 This function opens a system table, and return the first record. 265 @return first record of the system table */ 266 UNIV_INTERN 267 const rec_t* 268 dict_startscan_system( 269 /*==================*/ 270 btr_pcur_t* pcur, /*!< out: persistent cursor to 271 the record */ 272 mtr_t* mtr, /*!< in: the mini-transaction */ 273 dict_system_id_t system_id); /*!< in: which system table to open */ 274 /********************************************************************//** 275 This function get the next system table record as we scan the table. 276 @return the record if found, NULL if end of scan. */ 277 UNIV_INTERN 278 const rec_t* 279 dict_getnext_system( 280 /*================*/ 281 btr_pcur_t* pcur, /*!< in/out: persistent cursor 282 to the record */ 283 mtr_t* mtr); /*!< in: the mini-transaction */ 284 /********************************************************************//** 285 This function processes one SYS_TABLES record and populate the dict_table_t 286 struct for the table. Extracted out of dict_print() to be used by 287 both monitor table output and information schema innodb_sys_tables output. 288 @return error message, or NULL on success */ 289 UNIV_INTERN 290 const char* 291 dict_process_sys_tables_rec_and_mtr_commit( 292 /*=======================================*/ 293 mem_heap_t* heap, /*!< in: temporary memory heap */ 294 const rec_t* rec, /*!< in: SYS_TABLES record */ 295 dict_table_t** table, /*!< out: dict_table_t to fill */ 296 dict_table_info_t status, /*!< in: status bit controls 297 options such as whether we shall 298 look for dict_table_t from cache 299 first */ 300 mtr_t* mtr); /*!< in/out: mini-transaction, 301 will be committed */ 302 /********************************************************************//** 303 This function parses a SYS_INDEXES record and populate a dict_index_t 304 structure with the information from the record. For detail information 305 about SYS_INDEXES fields, please refer to dict_boot() function. 306 @return error message, or NULL on success */ 307 UNIV_INTERN 308 const char* 309 dict_process_sys_indexes_rec( 310 /*=========================*/ 311 mem_heap_t* heap, /*!< in/out: heap memory */ 312 const rec_t* rec, /*!< in: current SYS_INDEXES rec */ 313 dict_index_t* index, /*!< out: dict_index_t to be 314 filled */ 315 table_id_t* table_id); /*!< out: table id */ 316 /********************************************************************//** 317 This function parses a SYS_COLUMNS record and populate a dict_column_t 318 structure with the information from the record. 319 @return error message, or NULL on success */ 320 UNIV_INTERN 321 const char* 322 dict_process_sys_columns_rec( 323 /*=========================*/ 324 mem_heap_t* heap, /*!< in/out: heap memory */ 325 const rec_t* rec, /*!< in: current SYS_COLUMNS rec */ 326 dict_col_t* column, /*!< out: dict_col_t to be filled */ 327 table_id_t* table_id, /*!< out: table id */ 328 const char** col_name); /*!< out: column name */ 329 /********************************************************************//** 330 This function parses a SYS_FIELDS record and populate a dict_field_t 331 structure with the information from the record. 332 @return error message, or NULL on success */ 333 UNIV_INTERN 334 const char* 335 dict_process_sys_fields_rec( 336 /*========================*/ 337 mem_heap_t* heap, /*!< in/out: heap memory */ 338 const rec_t* rec, /*!< in: current SYS_FIELDS rec */ 339 dict_field_t* sys_field, /*!< out: dict_field_t to be 340 filled */ 341 ulint* pos, /*!< out: Field position */ 342 index_id_t* index_id, /*!< out: current index id */ 343 index_id_t last_id); /*!< in: previous index id */ 344 /********************************************************************//** 345 This function parses a SYS_FOREIGN record and populate a dict_foreign_t 346 structure with the information from the record. For detail information 347 about SYS_FOREIGN fields, please refer to dict_load_foreign() function 348 @return error message, or NULL on success */ 349 UNIV_INTERN 350 const char* 351 dict_process_sys_foreign_rec( 352 /*=========================*/ 353 mem_heap_t* heap, /*!< in/out: heap memory */ 354 const rec_t* rec, /*!< in: current SYS_FOREIGN rec */ 355 dict_foreign_t* foreign); /*!< out: dict_foreign_t to be 356 filled */ 357 /********************************************************************//** 358 This function parses a SYS_FOREIGN_COLS record and extract necessary 359 information from the record and return to caller. 360 @return error message, or NULL on success */ 361 UNIV_INTERN 362 const char* 363 dict_process_sys_foreign_col_rec( 364 /*=============================*/ 365 mem_heap_t* heap, /*!< in/out: heap memory */ 366 const rec_t* rec, /*!< in: current SYS_FOREIGN_COLS rec */ 367 const char** name, /*!< out: foreign key constraint name */ 368 const char** for_col_name, /*!< out: referencing column name */ 369 const char** ref_col_name, /*!< out: referenced column name 370 in referenced table */ 371 ulint* pos); /*!< out: column position */ 372 /********************************************************************//** 373 This function parses a SYS_TABLESPACES record, extracts necessary 374 information from the record and returns to caller. 375 @return error message, or NULL on success */ 376 UNIV_INTERN 377 const char* 378 dict_process_sys_tablespaces( 379 /*=========================*/ 380 mem_heap_t* heap, /*!< in/out: heap memory */ 381 const rec_t* rec, /*!< in: current SYS_TABLESPACES rec */ 382 ulint* space, /*!< out: pace id */ 383 const char** name, /*!< out: tablespace name */ 384 ulint* flags); /*!< out: tablespace flags */ 385 /********************************************************************//** 386 This function parses a SYS_DATAFILES record, extracts necessary 387 information from the record and returns to caller. 388 @return error message, or NULL on success */ 389 UNIV_INTERN 390 const char* 391 dict_process_sys_datafiles( 392 /*=======================*/ 393 mem_heap_t* heap, /*!< in/out: heap memory */ 394 const rec_t* rec, /*!< in: current SYS_DATAFILES rec */ 395 ulint* space, /*!< out: pace id */ 396 const char** path); /*!< out: datafile path */ 397 /********************************************************************//** 398 Get the filepath for a spaceid from SYS_DATAFILES. This function provides 399 a temporary heap which is used for the table lookup, but not for the path. 400 The caller must free the memory for the path returned. This function can 401 return NULL if the space ID is not found in SYS_DATAFILES, then the caller 402 will assume that the ibd file is in the normal datadir. 403 @return own: A copy of the first datafile found in SYS_DATAFILES.PATH for 404 the given space ID. NULL if space ID is zero or not found. */ 405 UNIV_INTERN 406 char* 407 dict_get_first_path( 408 /*================*/ 409 ulint space, /*!< in: space id */ 410 const char* name); /*!< in: tablespace name */ 411 /********************************************************************//** 412 Update the record for space_id in SYS_TABLESPACES to this filepath. 413 @return DB_SUCCESS if OK, dberr_t if the insert failed */ 414 UNIV_INTERN 415 dberr_t 416 dict_update_filepath( 417 /*=================*/ 418 ulint space_id, /*!< in: space id */ 419 const char* filepath); /*!< in: filepath */ 420 /********************************************************************//** 421 Insert records into SYS_TABLESPACES and SYS_DATAFILES. 422 @return DB_SUCCESS if OK, dberr_t if the insert failed */ 423 UNIV_INTERN 424 dberr_t 425 dict_insert_tablespace_and_filepath( 426 /*================================*/ 427 ulint space, /*!< in: space id */ 428 const char* name, /*!< in: talespace name */ 429 const char* filepath, /*!< in: filepath */ 430 ulint fsp_flags); /*!< in: tablespace flags */ 431 432 #ifndef UNIV_NONINL 433 #include "dict0load.ic" 434 #endif 435 436 #endif 437