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 SYS_ZIP_DICT, 56 SYS_ZIP_DICT_COLS, 57 58 /* This must be last item. Defines the number of system tables. */ 59 SYS_NUM_SYSTEM_TABLES 60 }; 61 62 /** Status bit for dict_process_sys_tables_rec_and_mtr_commit() */ 63 enum dict_table_info_t { 64 DICT_TABLE_LOAD_FROM_RECORD = 0,/*!< Directly populate a dict_table_t 65 structure with information from 66 a SYS_TABLES record */ 67 DICT_TABLE_LOAD_FROM_CACHE = 1 /*!< Check first whether dict_table_t 68 is in the cache, if so, return it */ 69 }; 70 71 /** Check type for dict_check_tablespaces_and_store_max_id() */ 72 enum dict_check_t { 73 /** No user tablespaces have been opened 74 (no crash recovery, no transactions recovered). */ 75 DICT_CHECK_NONE_LOADED = 0, 76 /** Some user tablespaces may have been opened 77 (no crash recovery; recovered table locks for transactions). */ 78 DICT_CHECK_SOME_LOADED, 79 /** All user tablespaces have been opened (crash recovery). */ 80 DICT_CHECK_ALL_LOADED 81 }; 82 83 /********************************************************************//** 84 In a crash recovery we already have all the tablespace objects created. 85 This function compares the space id information in the InnoDB data dictionary 86 to what we already read with fil_load_single_table_tablespaces(). 87 88 In a normal startup, we create the tablespace objects for every table in 89 InnoDB's data dictionary, if the corresponding .ibd file exists. 90 We also scan the biggest space id, and store it to fil_system. */ 91 UNIV_INTERN 92 void 93 dict_check_tablespaces_and_store_max_id( 94 /*====================================*/ 95 dict_check_t dict_check); /*!< in: how to check */ 96 /********************************************************************//** 97 Finds the first table name in the given database. 98 @return own: table name, NULL if does not exist; the caller must free 99 the memory in the string! */ 100 UNIV_INTERN 101 char* 102 dict_get_first_table_name_in_db( 103 /*============================*/ 104 const char* name); /*!< in: database name which ends to '/' */ 105 106 /********************************************************************//** 107 Loads a table definition from a SYS_TABLES record to dict_table_t. 108 Does not load any columns or indexes. 109 @return error message, or NULL on success */ 110 UNIV_INTERN 111 const char* 112 dict_load_table_low( 113 /*================*/ 114 const char* name, /*!< in: table name */ 115 const rec_t* rec, /*!< in: SYS_TABLES record */ 116 dict_table_t** table); /*!< out,own: table, or NULL */ 117 /********************************************************************//** 118 Loads a table column definition from a SYS_COLUMNS record to 119 dict_table_t. 120 @return error message, or NULL on success */ 121 UNIV_INTERN 122 const char* 123 dict_load_column_low( 124 /*=================*/ 125 dict_table_t* table, /*!< in/out: table, could be NULL 126 if we just populate a dict_column_t 127 struct with information from 128 a SYS_COLUMNS record */ 129 mem_heap_t* heap, /*!< in/out: memory heap 130 for temporary storage */ 131 dict_col_t* column, /*!< out: dict_column_t to fill, 132 or NULL if table != NULL */ 133 table_id_t* table_id, /*!< out: table id */ 134 const char** col_name, /*!< out: column name */ 135 const rec_t* rec); /*!< in: SYS_COLUMNS record */ 136 /********************************************************************//** 137 Loads an index definition from a SYS_INDEXES record to dict_index_t. 138 If allocate=TRUE, we will create a dict_index_t structure and fill it 139 accordingly. If allocated=FALSE, the dict_index_t will be supplied by 140 the caller and filled with information read from the record. @return 141 error message, or NULL on success */ 142 UNIV_INTERN 143 const char* 144 dict_load_index_low( 145 /*================*/ 146 byte* table_id, /*!< in/out: table id (8 bytes), 147 an "in" value if allocate=TRUE 148 and "out" when allocate=FALSE */ 149 const char* table_name, /*!< in: table name */ 150 mem_heap_t* heap, /*!< in/out: temporary memory heap */ 151 const rec_t* rec, /*!< in: SYS_INDEXES record */ 152 ibool allocate, /*!< in: TRUE=allocate *index, 153 FALSE=fill in a pre-allocated 154 *index */ 155 dict_index_t** index); /*!< out,own: index, or NULL */ 156 /********************************************************************//** 157 Loads an index field definition from a SYS_FIELDS record to 158 dict_index_t. 159 @return error message, or NULL on success */ 160 UNIV_INTERN 161 const char* 162 dict_load_field_low( 163 /*================*/ 164 byte* index_id, /*!< in/out: index id (8 bytes) 165 an "in" value if index != NULL 166 and "out" if index == NULL */ 167 dict_index_t* index, /*!< in/out: index, could be NULL 168 if we just populate a dict_field_t 169 struct with information from 170 a SYS_FIELDS record */ 171 dict_field_t* sys_field, /*!< out: dict_field_t to be 172 filled */ 173 ulint* pos, /*!< out: Field position */ 174 byte* last_index_id, /*!< in: last index id */ 175 mem_heap_t* heap, /*!< in/out: memory heap 176 for temporary storage */ 177 const rec_t* rec); /*!< in: SYS_FIELDS record */ 178 /********************************************************************//** 179 Using the table->heap, copy the null-terminated filepath into 180 table->data_dir_path and put a null byte before the extension. 181 This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path. 182 Make this data directory path only if it has not yet been saved. */ 183 UNIV_INTERN 184 void 185 dict_save_data_dir_path( 186 /*====================*/ 187 dict_table_t* table, /*!< in/out: table */ 188 char* filepath); /*!< in: filepath of tablespace */ 189 /*****************************************************************//** 190 Make sure the data_file_name is saved in dict_table_t if needed. Try to 191 read it from the file dictionary first, then from SYS_DATAFILES. */ 192 UNIV_INTERN 193 void 194 dict_get_and_save_data_dir_path( 195 /*============================*/ 196 dict_table_t* table, /*!< in/out: table */ 197 bool dict_mutex_own); /*!< in: true if dict_sys->mutex 198 is owned already */ 199 /********************************************************************//** 200 Loads a table definition and also all its index definitions, and also 201 the cluster definition if the table is a member in a cluster. Also loads 202 all foreign key constraints where the foreign key is in the table or where 203 a foreign key references columns in this table. 204 @return table, NULL if does not exist; if the table is stored in an 205 .ibd file, but the file does not exist, then we set the 206 ibd_file_missing flag TRUE in the table object we return */ 207 UNIV_INTERN 208 dict_table_t* 209 dict_load_table( 210 /*============*/ 211 const char* name, /*!< in: table name in the 212 databasename/tablename format */ 213 ibool cached, /*!< in: TRUE=add to cache, FALSE=do not */ 214 dict_err_ignore_t ignore_err); 215 /*!< in: error to be ignored when loading 216 table and its indexes' definition */ 217 /***********************************************************************//** 218 Loads a table object based on the table id. 219 @return table; NULL if table does not exist */ 220 UNIV_INTERN 221 dict_table_t* 222 dict_load_table_on_id( 223 /*==================*/ 224 table_id_t table_id, /*!< in: table id */ 225 dict_err_ignore_t ignore_err); /*!< in: errors to ignore 226 when loading the table */ 227 /********************************************************************//** 228 This function is called when the database is booted. 229 Loads system table index definitions except for the clustered index which 230 is added to the dictionary cache at booting before calling this function. */ 231 UNIV_INTERN 232 void 233 dict_load_sys_table( 234 /*================*/ 235 dict_table_t* table); /*!< in: system table */ 236 /***********************************************************************//** 237 Loads foreign key constraints where the table is either the foreign key 238 holder or where the table is referenced by a foreign key. Adds these 239 constraints to the data dictionary. Note that we know that the dictionary 240 cache already contains all constraints where the other relevant table is 241 already in the dictionary cache. 242 @return DB_SUCCESS or error code */ 243 UNIV_INTERN 244 dberr_t 245 dict_load_foreigns( 246 /*===============*/ 247 const char* table_name, /*!< in: table name */ 248 const char** col_names, /*!< in: column names, or NULL 249 to use table->col_names */ 250 bool check_recursive,/*!< in: Whether to check 251 recursive load of tables 252 chained by FK */ 253 bool check_charsets, /*!< in: whether to check 254 charset compatibility */ 255 dict_err_ignore_t ignore_err) /*!< in: error to be ignored */ 256 MY_ATTRIBUTE((nonnull(1), warn_unused_result)); 257 /********************************************************************//** 258 Prints to the standard output information on all tables found in the data 259 dictionary system table. */ 260 UNIV_INTERN 261 void 262 dict_print(void); 263 /*============*/ 264 265 /********************************************************************//** 266 This function opens a system table, and return the first record. 267 @return first record of the system table */ 268 UNIV_INTERN 269 const rec_t* 270 dict_startscan_system( 271 /*==================*/ 272 btr_pcur_t* pcur, /*!< out: persistent cursor to 273 the record */ 274 mtr_t* mtr, /*!< in: the mini-transaction */ 275 dict_system_id_t system_id); /*!< in: which system table to open */ 276 /********************************************************************//** 277 This function get the next system table record as we scan the table. 278 @return the record if found, NULL if end of scan. */ 279 UNIV_INTERN 280 const rec_t* 281 dict_getnext_system( 282 /*================*/ 283 btr_pcur_t* pcur, /*!< in/out: persistent cursor 284 to the record */ 285 mtr_t* mtr); /*!< in: the mini-transaction */ 286 /********************************************************************//** 287 This function processes one SYS_TABLES record and populate the dict_table_t 288 struct for the table. Extracted out of dict_print() to be used by 289 both monitor table output and information schema innodb_sys_tables output. 290 @return error message, or NULL on success */ 291 UNIV_INTERN 292 const char* 293 dict_process_sys_tables_rec_and_mtr_commit( 294 /*=======================================*/ 295 mem_heap_t* heap, /*!< in: temporary memory heap */ 296 const rec_t* rec, /*!< in: SYS_TABLES record */ 297 dict_table_t** table, /*!< out: dict_table_t to fill */ 298 dict_table_info_t status, /*!< in: status bit controls 299 options such as whether we shall 300 look for dict_table_t from cache 301 first */ 302 mtr_t* mtr); /*!< in/out: mini-transaction, 303 will be committed */ 304 /********************************************************************//** 305 This function parses a SYS_INDEXES record and populate a dict_index_t 306 structure with the information from the record. For detail information 307 about SYS_INDEXES fields, please refer to dict_boot() function. 308 @return error message, or NULL on success */ 309 UNIV_INTERN 310 const char* 311 dict_process_sys_indexes_rec( 312 /*=========================*/ 313 mem_heap_t* heap, /*!< in/out: heap memory */ 314 const rec_t* rec, /*!< in: current SYS_INDEXES rec */ 315 dict_index_t* index, /*!< out: dict_index_t to be 316 filled */ 317 table_id_t* table_id); /*!< out: table id */ 318 /********************************************************************//** 319 This function parses a SYS_COLUMNS record and populate a dict_column_t 320 structure with the information from the record. 321 @return error message, or NULL on success */ 322 UNIV_INTERN 323 const char* 324 dict_process_sys_columns_rec( 325 /*=========================*/ 326 mem_heap_t* heap, /*!< in/out: heap memory */ 327 const rec_t* rec, /*!< in: current SYS_COLUMNS rec */ 328 dict_col_t* column, /*!< out: dict_col_t to be filled */ 329 table_id_t* table_id, /*!< out: table id */ 330 const char** col_name); /*!< out: column name */ 331 /********************************************************************//** 332 This function parses a SYS_FIELDS record and populate a dict_field_t 333 structure with the information from the record. 334 @return error message, or NULL on success */ 335 UNIV_INTERN 336 const char* 337 dict_process_sys_fields_rec( 338 /*========================*/ 339 mem_heap_t* heap, /*!< in/out: heap memory */ 340 const rec_t* rec, /*!< in: current SYS_FIELDS rec */ 341 dict_field_t* sys_field, /*!< out: dict_field_t to be 342 filled */ 343 ulint* pos, /*!< out: Field position */ 344 index_id_t* index_id, /*!< out: current index id */ 345 index_id_t last_id); /*!< in: previous index id */ 346 /********************************************************************//** 347 This function parses a SYS_FOREIGN record and populate a dict_foreign_t 348 structure with the information from the record. For detail information 349 about SYS_FOREIGN fields, please refer to dict_load_foreign() function 350 @return error message, or NULL on success */ 351 UNIV_INTERN 352 const char* 353 dict_process_sys_foreign_rec( 354 /*=========================*/ 355 mem_heap_t* heap, /*!< in/out: heap memory */ 356 const rec_t* rec, /*!< in: current SYS_FOREIGN rec */ 357 dict_foreign_t* foreign); /*!< out: dict_foreign_t to be 358 filled */ 359 /********************************************************************//** 360 This function parses a SYS_FOREIGN_COLS record and extract necessary 361 information from the record and return to caller. 362 @return error message, or NULL on success */ 363 UNIV_INTERN 364 const char* 365 dict_process_sys_foreign_col_rec( 366 /*=============================*/ 367 mem_heap_t* heap, /*!< in/out: heap memory */ 368 const rec_t* rec, /*!< in: current SYS_FOREIGN_COLS rec */ 369 const char** name, /*!< out: foreign key constraint name */ 370 const char** for_col_name, /*!< out: referencing column name */ 371 const char** ref_col_name, /*!< out: referenced column name 372 in referenced table */ 373 ulint* pos); /*!< out: column position */ 374 /********************************************************************//** 375 This function parses a SYS_TABLESPACES record, extracts necessary 376 information from the record and returns to caller. 377 @return error message, or NULL on success */ 378 UNIV_INTERN 379 const char* 380 dict_process_sys_tablespaces( 381 /*=========================*/ 382 mem_heap_t* heap, /*!< in/out: heap memory */ 383 const rec_t* rec, /*!< in: current SYS_TABLESPACES rec */ 384 ulint* space, /*!< out: pace id */ 385 const char** name, /*!< out: tablespace name */ 386 ulint* flags); /*!< out: tablespace flags */ 387 /********************************************************************//** 388 This function parses a SYS_DATAFILES record, extracts necessary 389 information from the record and returns to caller. 390 @return error message, or NULL on success */ 391 UNIV_INTERN 392 const char* 393 dict_process_sys_datafiles( 394 /*=======================*/ 395 mem_heap_t* heap, /*!< in/out: heap memory */ 396 const rec_t* rec, /*!< in: current SYS_DATAFILES rec */ 397 ulint* space, /*!< out: pace id */ 398 const char** path); /*!< out: datafile path */ 399 400 /** This function parses a SYS_ZIP_DICT record, extracts necessary 401 information from the record and returns to caller. 402 @return error message, or NULL on success */ 403 UNIV_INTERN 404 const char* 405 dict_process_sys_zip_dict( 406 mem_heap_t* heap, /*!< in/out: heap memory */ 407 ulint zip_size, /*!< in: nonzero=compressed BLOB page size */ 408 const rec_t* rec, /*!< in: current SYS_ZIP_DICT rec */ 409 ulint* id, /*!< out: dict id */ 410 const char** name, /*!< out: dict name */ 411 const char** data, /*!< out: dict data */ 412 ulint* data_len); /*!< out: dict data length */ 413 414 /** This function parses a SYS_ZIP_DICT_COLS record, extracts necessary 415 information from the record and returns to caller. 416 @return error message, or NULL on success */ 417 UNIV_INTERN 418 const char* 419 dict_process_sys_zip_dict_cols( 420 mem_heap_t* heap, /*!< in/out: heap memory */ 421 const rec_t* rec, /*!< in: current SYS_ZIP_DICT rec */ 422 ulint* table_id, /*!< out: table id */ 423 ulint* column_pos, /*!< out: column position */ 424 ulint* dict_id); /*!< out: dict id */ 425 426 /********************************************************************//** 427 Get the filepath for a spaceid from SYS_DATAFILES. This function provides 428 a temporary heap which is used for the table lookup, but not for the path. 429 The caller must free the memory for the path returned. This function can 430 return NULL if the space ID is not found in SYS_DATAFILES, then the caller 431 will assume that the ibd file is in the normal datadir. 432 @return own: A copy of the first datafile found in SYS_DATAFILES.PATH for 433 the given space ID. NULL if space ID is zero or not found. */ 434 UNIV_INTERN 435 char* 436 dict_get_first_path( 437 /*================*/ 438 ulint space, /*!< in: space id */ 439 const char* name); /*!< in: tablespace name */ 440 /********************************************************************//** 441 Update the record for space_id in SYS_TABLESPACES to this filepath. 442 @return DB_SUCCESS if OK, dberr_t if the insert failed */ 443 UNIV_INTERN 444 dberr_t 445 dict_update_filepath( 446 /*=================*/ 447 ulint space_id, /*!< in: space id */ 448 const char* filepath); /*!< in: filepath */ 449 /********************************************************************//** 450 Insert records into SYS_TABLESPACES and SYS_DATAFILES. 451 @return DB_SUCCESS if OK, dberr_t if the insert failed */ 452 UNIV_INTERN 453 dberr_t 454 dict_insert_tablespace_and_filepath( 455 /*================================*/ 456 ulint space, /*!< in: space id */ 457 const char* name, /*!< in: talespace name */ 458 const char* filepath, /*!< in: filepath */ 459 ulint fsp_flags); /*!< in: tablespace flags */ 460 461 #ifndef UNIV_NONINL 462 #include "dict0load.ic" 463 #endif 464 465 #endif 466