#include "dict0load.h"#include "mysql_version.h"#include "btr0pcur.h"#include "btr0btr.h"#include "page0page.h"#include "mach0data.h"#include "dict0dict.h"#include "dict0boot.h"#include "rem0cmp.h"#include "srv0start.h"#include "srv0srv.h"Include dependency graph for dict0load.c:

Go to the source code of this file.
Functions | |
| char * | dict_get_first_table_name_in_db (const char *name) |
| void | dict_print (void) |
| void | dict_check_tablespaces_and_store_max_id (ibool in_crash_recovery) |
| static void | dict_load_columns (dict_table_t *table, mem_heap_t *heap) |
| static void | dict_load_report_deleted_index (const char *name, ulint field) |
| static void | dict_load_fields (dict_table_t *table, dict_index_t *index, mem_heap_t *heap) |
| static ibool | dict_load_indexes (dict_table_t *table, mem_heap_t *heap) |
| dict_table_t * | dict_load_table (const char *name) |
| dict_table_t * | dict_load_table_on_id (dulint table_id) |
| void | dict_load_sys_table (dict_table_t *table) |
| static void | dict_load_foreign_cols (const char *id, dict_foreign_t *foreign) |
| static ulint | dict_load_foreign (const char *id, ibool check_charsets) |
| ulint | dict_load_foreigns (const char *table_name, ibool check_charsets) |
| void dict_check_tablespaces_and_store_max_id | ( | ibool | in_crash_recovery | ) |
Definition at line 218 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_at_index_side(), btr_pcur_restore_position(), btr_pcur_store_position(), BTR_SEARCH_LEAF, dict_sys, dict_table_get_low(), dict_table_is_comp(), FALSE, fil_open_single_table_tablespace(), fil_set_max_space_id_if_bigger(), fil_space_for_table_exists_in_mem(), dict_table_struct::indexes, mach_read_from_4(), mem_free, mem_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), name, rec_get_deleted_flag(), rec_get_nth_field_old(), TRUE, ut_a, and UT_LIST_GET_FIRST.
Referenced by innobase_start_or_create_for_mysql().
00220 : are we doing a crash recovery */ 00221 { 00222 dict_table_t* sys_tables; 00223 dict_index_t* sys_index; 00224 btr_pcur_t pcur; 00225 rec_t* rec; 00226 byte* field; 00227 ulint len; 00228 ulint space_id; 00229 ulint max_space_id = 0; 00230 mtr_t mtr; 00231 00232 mutex_enter(&(dict_sys->mutex)); 00233 00234 mtr_start(&mtr); 00235 00236 sys_tables = dict_table_get_low("SYS_TABLES"); 00237 sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); 00238 ut_a(!dict_table_is_comp(sys_tables)); 00239 00240 btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur, 00241 TRUE, &mtr); 00242 loop: 00243 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00244 00245 rec = btr_pcur_get_rec(&pcur); 00246 00247 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 00248 /* end of index */ 00249 00250 btr_pcur_close(&pcur); 00251 mtr_commit(&mtr); 00252 00253 /* We must make the tablespace cache aware of the biggest 00254 known space id */ 00255 00256 /* printf("Biggest space id in data dictionary %lu\n", 00257 max_space_id); */ 00258 fil_set_max_space_id_if_bigger(max_space_id); 00259 00260 mutex_exit(&(dict_sys->mutex)); 00261 00262 return; 00263 } 00264 00265 field = rec_get_nth_field_old(rec, 0, &len); 00266 00267 if (!rec_get_deleted_flag(rec, 0)) { 00268 00269 /* We found one */ 00270 00271 char* name = mem_strdupl((char*) field, len); 00272 00273 field = rec_get_nth_field_old(rec, 9, &len); 00274 ut_a(len == 4); 00275 00276 space_id = mach_read_from_4(field); 00277 00278 btr_pcur_store_position(&pcur, &mtr); 00279 00280 mtr_commit(&mtr); 00281 00282 if (space_id != 0 && in_crash_recovery) { 00283 /* Check that the tablespace (the .ibd file) really 00284 exists; print a warning to the .err log if not */ 00285 00286 fil_space_for_table_exists_in_mem(space_id, name, 00287 FALSE, TRUE, TRUE); 00288 } 00289 00290 if (space_id != 0 && !in_crash_recovery) { 00291 /* It is a normal database startup: create the space 00292 object and check that the .ibd file exists. */ 00293 00294 fil_open_single_table_tablespace(FALSE, space_id, 00295 name); 00296 } 00297 00298 mem_free(name); 00299 00300 if (space_id > max_space_id) { 00301 max_space_id = space_id; 00302 } 00303 00304 mtr_start(&mtr); 00305 00306 btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); 00307 } 00308 00309 goto loop; 00310 }
Here is the call graph for this function:

Here is the caller graph for this function:

| char* dict_get_first_table_name_in_db | ( | const char * | name | ) |
Definition at line 33 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, dfield_set_data(), dict_index_copy_types(), dict_sys, dict_table_get_low(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), dict_table_struct::indexes, mem_heap_create, mem_heap_free, mem_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, NULL, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), strlen(), ut_a, ut_ad, UT_LIST_GET_FIRST, ut_memcmp(), and ut_strlen().
Referenced by row_drop_database_for_mysql().
00035 : table name, NULL if 00036 does not exist; the caller must 00037 free the memory in the string! */ 00038 const char* name) /* in: database name which ends in '/' */ 00039 { 00040 dict_table_t* sys_tables; 00041 btr_pcur_t pcur; 00042 dict_index_t* sys_index; 00043 dtuple_t* tuple; 00044 mem_heap_t* heap; 00045 dfield_t* dfield; 00046 rec_t* rec; 00047 byte* field; 00048 ulint len; 00049 mtr_t mtr; 00050 00051 #ifdef UNIV_SYNC_DEBUG 00052 ut_ad(mutex_own(&(dict_sys->mutex))); 00053 #endif /* UNIV_SYNC_DEBUG */ 00054 00055 heap = mem_heap_create(1000); 00056 00057 mtr_start(&mtr); 00058 00059 sys_tables = dict_table_get_low("SYS_TABLES"); 00060 sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); 00061 ut_a(!dict_table_is_comp(sys_tables)); 00062 00063 tuple = dtuple_create(heap, 1); 00064 dfield = dtuple_get_nth_field(tuple, 0); 00065 00066 dfield_set_data(dfield, name, ut_strlen(name)); 00067 dict_index_copy_types(tuple, sys_index, 1); 00068 00069 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 00070 BTR_SEARCH_LEAF, &pcur, &mtr); 00071 loop: 00072 rec = btr_pcur_get_rec(&pcur); 00073 00074 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 00075 /* Not found */ 00076 00077 btr_pcur_close(&pcur); 00078 mtr_commit(&mtr); 00079 mem_heap_free(heap); 00080 00081 return(NULL); 00082 } 00083 00084 field = rec_get_nth_field_old(rec, 0, &len); 00085 00086 if (len < strlen(name) 00087 || ut_memcmp(name, field, strlen(name)) != 0) { 00088 /* Not found */ 00089 00090 btr_pcur_close(&pcur); 00091 mtr_commit(&mtr); 00092 mem_heap_free(heap); 00093 00094 return(NULL); 00095 } 00096 00097 if (!rec_get_deleted_flag(rec, 0)) { 00098 00099 /* We found one */ 00100 00101 char* table_name = mem_strdupl((char*) field, len); 00102 00103 btr_pcur_close(&pcur); 00104 mtr_commit(&mtr); 00105 mem_heap_free(heap); 00106 00107 return(table_name); 00108 } 00109 00110 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00111 00112 goto loop; 00113 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_load_columns | ( | dict_table_t * | table, | |
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 316 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, buf, DATA_MYSQL_BINARY_CHARSET_COLL, data_mysql_default_charset_coll, DATA_N_SYS_COLS, dfield_set_data(), dict_field_get_col(), dict_index_copy_types(), dict_index_get_nth_field(), dict_mem_table_add_col(), dict_sys, dict_table_get_low(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), dtype_form_prtype(), dtype_get_charset_coll(), dtype_is_binary_string_type(), dtype_is_string_type(), dict_table_struct::id, dict_table_struct::indexes, mach_read_from_4(), mach_read_from_8(), mach_write_to_8(), mem_heap_alloc(), mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, dict_table_struct::n_cols, name, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), ut_a, ut_ad, ut_dulint_cmp(), UT_LIST_GET_FIRST, and ut_strcmp().
Referenced by dict_load_table().
00318 : table */ 00319 mem_heap_t* heap) /* in: memory heap for temporary storage */ 00320 { 00321 dict_table_t* sys_columns; 00322 dict_index_t* sys_index; 00323 btr_pcur_t pcur; 00324 dtuple_t* tuple; 00325 dfield_t* dfield; 00326 rec_t* rec; 00327 byte* field; 00328 ulint len; 00329 byte* buf; 00330 char* name; 00331 ulint mtype; 00332 ulint prtype; 00333 ulint col_len; 00334 ulint prec; 00335 ulint i; 00336 mtr_t mtr; 00337 00338 #ifdef UNIV_SYNC_DEBUG 00339 ut_ad(mutex_own(&(dict_sys->mutex))); 00340 #endif /* UNIV_SYNC_DEBUG */ 00341 00342 mtr_start(&mtr); 00343 00344 sys_columns = dict_table_get_low("SYS_COLUMNS"); 00345 sys_index = UT_LIST_GET_FIRST(sys_columns->indexes); 00346 ut_a(!dict_table_is_comp(sys_columns)); 00347 00348 tuple = dtuple_create(heap, 1); 00349 dfield = dtuple_get_nth_field(tuple, 0); 00350 00351 buf = mem_heap_alloc(heap, 8); 00352 mach_write_to_8(buf, table->id); 00353 00354 dfield_set_data(dfield, buf, 8); 00355 dict_index_copy_types(tuple, sys_index, 1); 00356 00357 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 00358 BTR_SEARCH_LEAF, &pcur, &mtr); 00359 for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) { 00360 00361 rec = btr_pcur_get_rec(&pcur); 00362 00363 ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); 00364 00365 ut_a(!rec_get_deleted_flag(rec, 0)); 00366 00367 field = rec_get_nth_field_old(rec, 0, &len); 00368 ut_ad(len == 8); 00369 ut_a(ut_dulint_cmp(table->id, mach_read_from_8(field)) == 0); 00370 00371 field = rec_get_nth_field_old(rec, 1, &len); 00372 ut_ad(len == 4); 00373 ut_a(i == mach_read_from_4(field)); 00374 00375 ut_a(0 == ut_strcmp("NAME", 00376 dict_field_get_col( 00377 dict_index_get_nth_field(sys_index, 4))->name)); 00378 00379 field = rec_get_nth_field_old(rec, 4, &len); 00380 name = mem_heap_strdupl(heap, (char*) field, len); 00381 00382 field = rec_get_nth_field_old(rec, 5, &len); 00383 mtype = mach_read_from_4(field); 00384 00385 field = rec_get_nth_field_old(rec, 6, &len); 00386 prtype = mach_read_from_4(field); 00387 00388 if (dtype_get_charset_coll(prtype) == 0 00389 && dtype_is_string_type(mtype)) { 00390 /* The table was created with < 4.1.2. */ 00391 00392 if (dtype_is_binary_string_type(mtype, prtype)) { 00393 /* Use the binary collation for 00394 string columns of binary type. */ 00395 00396 prtype = dtype_form_prtype(prtype, 00397 DATA_MYSQL_BINARY_CHARSET_COLL); 00398 } else { 00399 /* Use the default charset for 00400 other than binary columns. */ 00401 00402 prtype = dtype_form_prtype(prtype, 00403 data_mysql_default_charset_coll); 00404 } 00405 } 00406 00407 field = rec_get_nth_field_old(rec, 7, &len); 00408 col_len = mach_read_from_4(field); 00409 00410 ut_a(0 == ut_strcmp("PREC", 00411 dict_field_get_col( 00412 dict_index_get_nth_field(sys_index, 8))->name)); 00413 00414 field = rec_get_nth_field_old(rec, 8, &len); 00415 prec = mach_read_from_4(field); 00416 00417 dict_mem_table_add_col(table, name, mtype, prtype, col_len, 00418 prec); 00419 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00420 } 00421 00422 btr_pcur_close(&pcur); 00423 mtr_commit(&mtr); 00424 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_load_fields | ( | dict_table_t * | table, | |
| dict_index_t * | index, | |||
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 449 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, buf, dfield_set_data(), dict_field_get_col(), dict_index_copy_types(), dict_index_get_nth_field(), dict_load_report_deleted_index(), dict_mem_index_add_field(), dict_sys, dict_table_get_low(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), index(), dict_table_struct::indexes, mach_read_from_4(), mach_write_to_8(), mem_heap_alloc(), mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, name, dict_table_struct::name, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), ut_a, ut_ad, UT_LIST_GET_FIRST, ut_memcmp(), UT_NOT_USED, and ut_strcmp().
Referenced by dict_load_indexes().
00451 : table */ 00452 dict_index_t* index, /* in: index whose fields to load */ 00453 mem_heap_t* heap) /* in: memory heap for temporary storage */ 00454 { 00455 dict_table_t* sys_fields; 00456 dict_index_t* sys_index; 00457 btr_pcur_t pcur; 00458 dtuple_t* tuple; 00459 dfield_t* dfield; 00460 ulint pos_and_prefix_len; 00461 ulint prefix_len; 00462 rec_t* rec; 00463 byte* field; 00464 ulint len; 00465 byte* buf; 00466 ulint i; 00467 mtr_t mtr; 00468 00469 #ifdef UNIV_SYNC_DEBUG 00470 ut_ad(mutex_own(&(dict_sys->mutex))); 00471 #endif /* UNIV_SYNC_DEBUG */ 00472 00473 UT_NOT_USED(table); 00474 00475 mtr_start(&mtr); 00476 00477 sys_fields = dict_table_get_low("SYS_FIELDS"); 00478 sys_index = UT_LIST_GET_FIRST(sys_fields->indexes); 00479 ut_a(!dict_table_is_comp(sys_fields)); 00480 00481 tuple = dtuple_create(heap, 1); 00482 dfield = dtuple_get_nth_field(tuple, 0); 00483 00484 buf = mem_heap_alloc(heap, 8); 00485 mach_write_to_8(buf, index->id); 00486 00487 dfield_set_data(dfield, buf, 8); 00488 dict_index_copy_types(tuple, sys_index, 1); 00489 00490 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 00491 BTR_SEARCH_LEAF, &pcur, &mtr); 00492 for (i = 0; i < index->n_fields; i++) { 00493 00494 rec = btr_pcur_get_rec(&pcur); 00495 00496 ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); 00497 if (rec_get_deleted_flag(rec, 0)) { 00498 dict_load_report_deleted_index(table->name, i); 00499 } 00500 00501 field = rec_get_nth_field_old(rec, 0, &len); 00502 ut_ad(len == 8); 00503 ut_a(ut_memcmp(buf, field, len) == 0); 00504 00505 field = rec_get_nth_field_old(rec, 1, &len); 00506 ut_a(len == 4); 00507 00508 /* The next field stores the field position in the index 00509 and a possible column prefix length if the index field 00510 does not contain the whole column. The storage format is 00511 like this: if there is at least one prefix field in the index, 00512 then the HIGH 2 bytes contain the field number (== i) and the 00513 low 2 bytes the prefix length for the field. Otherwise the 00514 field number (== i) is contained in the 2 LOW bytes. */ 00515 00516 pos_and_prefix_len = mach_read_from_4(field); 00517 00518 ut_a((pos_and_prefix_len & 0xFFFFUL) == i 00519 || (pos_and_prefix_len & 0xFFFF0000UL) == (i << 16)); 00520 00521 if ((i == 0 && pos_and_prefix_len > 0) 00522 || (pos_and_prefix_len & 0xFFFF0000UL) > 0) { 00523 00524 prefix_len = pos_and_prefix_len & 0xFFFFUL; 00525 } else { 00526 prefix_len = 0; 00527 } 00528 00529 ut_a(0 == ut_strcmp("COL_NAME", 00530 dict_field_get_col( 00531 dict_index_get_nth_field(sys_index, 4))->name)); 00532 00533 field = rec_get_nth_field_old(rec, 4, &len); 00534 00535 dict_mem_index_add_field(index, 00536 mem_heap_strdupl(heap, (char*) field, len), prefix_len); 00537 00538 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00539 } 00540 00541 btr_pcur_close(&pcur); 00542 mtr_commit(&mtr); 00543 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ulint dict_load_foreign | ( | const char * | id, | |
| ibool | check_charsets | |||
| ) | [static] |
Definition at line 1083 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, DB_ERROR, dfield_set_data(), dict_foreign_add_to_cache(), dict_index_copy_types(), dict_load_foreign_cols(), dict_mem_foreign_create(), dict_sys, dict_table_get_low(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), dict_foreign_struct::foreign_table_name, dict_foreign_struct::heap, dict_foreign_struct::id, dict_table_struct::indexes, mach_read_from_4(), mem_heap_create, mem_heap_free, mem_heap_strdup(), mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, dict_foreign_struct::n_fields, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), dict_foreign_struct::referenced_table_name, dict_foreign_struct::type, ut_a, ut_ad, UT_LIST_GET_FIRST, ut_memcmp(), and ut_strlen().
Referenced by dict_load_foreigns().
01085 : DB_SUCCESS or error code */ 01086 const char* id, /* in: foreign constraint id as a 01087 null-terminated string */ 01088 ibool check_charsets)/* in: TRUE=check charset compatibility */ 01089 { 01090 dict_foreign_t* foreign; 01091 dict_table_t* sys_foreign; 01092 btr_pcur_t pcur; 01093 dict_index_t* sys_index; 01094 dtuple_t* tuple; 01095 mem_heap_t* heap2; 01096 dfield_t* dfield; 01097 rec_t* rec; 01098 byte* field; 01099 ulint len; 01100 mtr_t mtr; 01101 01102 #ifdef UNIV_SYNC_DEBUG 01103 ut_ad(mutex_own(&(dict_sys->mutex))); 01104 #endif /* UNIV_SYNC_DEBUG */ 01105 01106 heap2 = mem_heap_create(1000); 01107 01108 mtr_start(&mtr); 01109 01110 sys_foreign = dict_table_get_low("SYS_FOREIGN"); 01111 sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes); 01112 ut_a(!dict_table_is_comp(sys_foreign)); 01113 01114 tuple = dtuple_create(heap2, 1); 01115 dfield = dtuple_get_nth_field(tuple, 0); 01116 01117 dfield_set_data(dfield, id, ut_strlen(id)); 01118 dict_index_copy_types(tuple, sys_index, 1); 01119 01120 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 01121 BTR_SEARCH_LEAF, &pcur, &mtr); 01122 rec = btr_pcur_get_rec(&pcur); 01123 01124 if (!btr_pcur_is_on_user_rec(&pcur, &mtr) 01125 || rec_get_deleted_flag(rec, 0)) { 01126 /* Not found */ 01127 01128 fprintf(stderr, 01129 "InnoDB: Error A: cannot load foreign constraint %s\n", 01130 id); 01131 01132 btr_pcur_close(&pcur); 01133 mtr_commit(&mtr); 01134 mem_heap_free(heap2); 01135 01136 return(DB_ERROR); 01137 } 01138 01139 field = rec_get_nth_field_old(rec, 0, &len); 01140 01141 /* Check if the id in record is the searched one */ 01142 if (len != ut_strlen(id) || ut_memcmp(id, field, len) != 0) { 01143 01144 fprintf(stderr, 01145 "InnoDB: Error B: cannot load foreign constraint %s\n", 01146 id); 01147 01148 btr_pcur_close(&pcur); 01149 mtr_commit(&mtr); 01150 mem_heap_free(heap2); 01151 01152 return(DB_ERROR); 01153 } 01154 01155 /* Read the table names and the number of columns associated 01156 with the constraint */ 01157 01158 mem_heap_free(heap2); 01159 01160 foreign = dict_mem_foreign_create(); 01161 01162 foreign->n_fields = 01163 mach_read_from_4(rec_get_nth_field_old(rec, 5, &len)); 01164 01165 ut_a(len == 4); 01166 01167 /* We store the type to the bits 24-31 of n_fields */ 01168 01169 foreign->type = foreign->n_fields >> 24; 01170 foreign->n_fields = foreign->n_fields & 0xFFFFFFUL; 01171 01172 foreign->id = mem_heap_strdup(foreign->heap, id); 01173 01174 field = rec_get_nth_field_old(rec, 3, &len); 01175 foreign->foreign_table_name = 01176 mem_heap_strdupl(foreign->heap, (char*) field, len); 01177 01178 field = rec_get_nth_field_old(rec, 4, &len); 01179 foreign->referenced_table_name = 01180 mem_heap_strdupl(foreign->heap, (char*) field, len); 01181 01182 btr_pcur_close(&pcur); 01183 mtr_commit(&mtr); 01184 01185 dict_load_foreign_cols(id, foreign); 01186 01187 /* If the foreign table is not yet in the dictionary cache, we 01188 have to load it so that we are able to make type comparisons 01189 in the next function call. */ 01190 01191 dict_table_get_low(foreign->foreign_table_name); 01192 01193 /* Note that there may already be a foreign constraint object in 01194 the dictionary cache for this constraint: then the following 01195 call only sets the pointers in it to point to the appropriate table 01196 and index objects and frees the newly created object foreign. 01197 Adding to the cache should always succeed since we are not creating 01198 a new foreign key constraint but loading one from the data 01199 dictionary. */ 01200 01201 return(dict_foreign_add_to_cache(foreign, check_charsets)); 01202 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_load_foreign_cols | ( | const char * | id, | |
| dict_foreign_t * | foreign | |||
| ) | [static] |
Definition at line 1009 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, dfield_set_data(), dict_index_copy_types(), dict_sys, dict_table_get_low(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), dict_foreign_struct::foreign_col_names, dict_foreign_struct::heap, dict_table_struct::indexes, mach_read_from_4(), mem_heap_alloc(), mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, dict_foreign_struct::n_fields, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), dict_foreign_struct::referenced_col_names, ut_a, ut_ad, UT_LIST_GET_FIRST, ut_memcmp(), and ut_strlen().
Referenced by dict_load_foreign().
01011 : foreign constraint id as a null- 01012 terminated string */ 01013 dict_foreign_t* foreign)/* in: foreign constraint object */ 01014 { 01015 dict_table_t* sys_foreign_cols; 01016 dict_index_t* sys_index; 01017 btr_pcur_t pcur; 01018 dtuple_t* tuple; 01019 dfield_t* dfield; 01020 rec_t* rec; 01021 byte* field; 01022 ulint len; 01023 ulint i; 01024 mtr_t mtr; 01025 01026 #ifdef UNIV_SYNC_DEBUG 01027 ut_ad(mutex_own(&(dict_sys->mutex))); 01028 #endif /* UNIV_SYNC_DEBUG */ 01029 01030 foreign->foreign_col_names = mem_heap_alloc(foreign->heap, 01031 foreign->n_fields * sizeof(void*)); 01032 01033 foreign->referenced_col_names = mem_heap_alloc(foreign->heap, 01034 foreign->n_fields * sizeof(void*)); 01035 mtr_start(&mtr); 01036 01037 sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS"); 01038 sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes); 01039 ut_a(!dict_table_is_comp(sys_foreign_cols)); 01040 01041 tuple = dtuple_create(foreign->heap, 1); 01042 dfield = dtuple_get_nth_field(tuple, 0); 01043 01044 dfield_set_data(dfield, id, ut_strlen(id)); 01045 dict_index_copy_types(tuple, sys_index, 1); 01046 01047 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 01048 BTR_SEARCH_LEAF, &pcur, &mtr); 01049 for (i = 0; i < foreign->n_fields; i++) { 01050 01051 rec = btr_pcur_get_rec(&pcur); 01052 01053 ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); 01054 ut_a(!rec_get_deleted_flag(rec, 0)); 01055 01056 field = rec_get_nth_field_old(rec, 0, &len); 01057 ut_a(len == ut_strlen(id)); 01058 ut_a(ut_memcmp(id, field, len) == 0); 01059 01060 field = rec_get_nth_field_old(rec, 1, &len); 01061 ut_a(len == 4); 01062 ut_a(i == mach_read_from_4(field)); 01063 01064 field = rec_get_nth_field_old(rec, 4, &len); 01065 foreign->foreign_col_names[i] = 01066 mem_heap_strdupl(foreign->heap, (char*) field, len); 01067 01068 field = rec_get_nth_field_old(rec, 5, &len); 01069 foreign->referenced_col_names[i] = 01070 mem_heap_strdupl(foreign->heap, (char*) field, len); 01071 01072 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 01073 } 01074 01075 btr_pcur_close(&pcur); 01076 mtr_commit(&mtr); 01077 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint dict_load_foreigns | ( | const char * | table_name, | |
| ibool | check_charsets | |||
| ) |
Definition at line 1212 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_on_user_rec(), btr_pcur_restore_position(), btr_pcur_store_position(), BTR_SEARCH_LEAF, cmp_data_data(), DB_ERROR, DB_SUCCESS, dfield_get_data(), dfield_get_len(), dfield_get_type(), dfield_set_data(), dict_index_copy_types(), dict_load_foreign(), dict_sys, dict_table_get_first_index(), dict_table_get_low(), dict_table_get_next_index(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), err, id, mem_heap_create, mem_heap_free, mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, NULL, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), ut_a, ut_ad, ut_memcmp(), and ut_strlen().
Referenced by dict_load_table(), row_rename_table_for_mysql(), and row_table_add_foreign_constraints().
01214 : DB_SUCCESS or error code */ 01215 const char* table_name, /* in: table name */ 01216 ibool check_charsets) /* in: TRUE=check charset 01217 compatibility */ 01218 { 01219 btr_pcur_t pcur; 01220 mem_heap_t* heap; 01221 dtuple_t* tuple; 01222 dfield_t* dfield; 01223 dict_index_t* sec_index; 01224 dict_table_t* sys_foreign; 01225 rec_t* rec; 01226 byte* field; 01227 ulint len; 01228 char* id ; 01229 ulint err; 01230 mtr_t mtr; 01231 01232 #ifdef UNIV_SYNC_DEBUG 01233 ut_ad(mutex_own(&(dict_sys->mutex))); 01234 #endif /* UNIV_SYNC_DEBUG */ 01235 01236 sys_foreign = dict_table_get_low("SYS_FOREIGN"); 01237 01238 if (sys_foreign == NULL) { 01239 /* No foreign keys defined yet in this database */ 01240 01241 fprintf(stderr, 01242 "InnoDB: Error: no foreign key system tables in the database\n"); 01243 01244 return(DB_ERROR); 01245 } 01246 01247 ut_a(!dict_table_is_comp(sys_foreign)); 01248 mtr_start(&mtr); 01249 01250 /* Get the secondary index based on FOR_NAME from table 01251 SYS_FOREIGN */ 01252 01253 sec_index = dict_table_get_next_index( 01254 dict_table_get_first_index(sys_foreign)); 01255 start_load: 01256 heap = mem_heap_create(256); 01257 01258 tuple = dtuple_create(heap, 1); 01259 dfield = dtuple_get_nth_field(tuple, 0); 01260 01261 dfield_set_data(dfield, table_name, ut_strlen(table_name)); 01262 dict_index_copy_types(tuple, sec_index, 1); 01263 01264 btr_pcur_open_on_user_rec(sec_index, tuple, PAGE_CUR_GE, 01265 BTR_SEARCH_LEAF, &pcur, &mtr); 01266 loop: 01267 rec = btr_pcur_get_rec(&pcur); 01268 01269 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 01270 /* End of index */ 01271 01272 goto load_next_index; 01273 } 01274 01275 /* Now we have the record in the secondary index containing a table 01276 name and a foreign constraint ID */ 01277 01278 rec = btr_pcur_get_rec(&pcur); 01279 field = rec_get_nth_field_old(rec, 0, &len); 01280 01281 /* Check if the table name in the record is the one searched for; the 01282 following call does the comparison in the latin1_swedish_ci 01283 charset-collation, in a case-insensitive way. */ 01284 01285 if (0 != cmp_data_data(dfield_get_type(dfield), 01286 dfield_get_data(dfield), dfield_get_len(dfield), 01287 field, len)) { 01288 01289 goto load_next_index; 01290 } 01291 01292 /* Since table names in SYS_FOREIGN are stored in a case-insensitive 01293 order, we have to check that the table name matches also in a binary 01294 string comparison. On Unix, MySQL allows table names that only differ 01295 in character case. */ 01296 01297 if (0 != ut_memcmp(field, table_name, len)) { 01298 01299 goto next_rec; 01300 } 01301 01302 if (rec_get_deleted_flag(rec, 0)) { 01303 01304 goto next_rec; 01305 } 01306 01307 /* Now we get a foreign key constraint id */ 01308 field = rec_get_nth_field_old(rec, 1, &len); 01309 id = mem_heap_strdupl(heap, (char*) field, len); 01310 01311 btr_pcur_store_position(&pcur, &mtr); 01312 01313 mtr_commit(&mtr); 01314 01315 /* Load the foreign constraint definition to the dictionary cache */ 01316 01317 err = dict_load_foreign(id, check_charsets); 01318 01319 if (err != DB_SUCCESS) { 01320 btr_pcur_close(&pcur); 01321 mem_heap_free(heap); 01322 01323 return(err); 01324 } 01325 01326 mtr_start(&mtr); 01327 01328 btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); 01329 next_rec: 01330 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 01331 01332 goto loop; 01333 01334 load_next_index: 01335 btr_pcur_close(&pcur); 01336 mtr_commit(&mtr); 01337 mem_heap_free(heap); 01338 01339 sec_index = dict_table_get_next_index(sec_index); 01340 01341 if (sec_index != NULL) { 01342 01343 mtr_start(&mtr); 01344 01345 goto start_load; 01346 } 01347 01348 return(DB_SUCCESS); 01349 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ibool dict_load_indexes | ( | dict_table_t * | table, | |
| mem_heap_t * | heap | |||
| ) | [static] |
Definition at line 550 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, buf, dfield_set_data(), DICT_CLUSTERED, dict_field_get_col(), DICT_HDR_FIRST_ID, dict_index_add_to_cache(), dict_index_copy_types(), dict_index_get_nth_field(), dict_load_fields(), dict_load_report_deleted_index(), dict_mem_index_create(), dict_sys, dict_table_get_first_index(), dict_table_get_low(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), FALSE, FIL_NULL, dict_table_struct::id, id, index(), dict_table_struct::indexes, mach_read_from_4(), mach_read_from_8(), mach_write_to_8(), mem_heap_alloc(), mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, name, dict_table_struct::name, NULL, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), dict_sys_struct::sys_tables, TRUE, ut_a, ut_ad, ut_dulint_get_high(), ut_dulint_get_low(), UT_LIST_GET_FIRST, ut_memcmp(), and ut_strcmp().
Referenced by dict_load_sys_table(), and dict_load_table().
00552 : TRUE if ok, FALSE if corruption 00553 of dictionary table */ 00554 dict_table_t* table, /* in: table */ 00555 mem_heap_t* heap) /* in: memory heap for temporary storage */ 00556 { 00557 dict_table_t* sys_indexes; 00558 dict_index_t* sys_index; 00559 dict_index_t* index; 00560 btr_pcur_t pcur; 00561 dtuple_t* tuple; 00562 dfield_t* dfield; 00563 rec_t* rec; 00564 byte* field; 00565 ulint len; 00566 ulint name_len; 00567 char* name_buf; 00568 ulint type; 00569 ulint space; 00570 ulint page_no; 00571 ulint n_fields; 00572 byte* buf; 00573 ibool is_sys_table; 00574 dulint id; 00575 mtr_t mtr; 00576 00577 #ifdef UNIV_SYNC_DEBUG 00578 ut_ad(mutex_own(&(dict_sys->mutex))); 00579 #endif /* UNIV_SYNC_DEBUG */ 00580 00581 if ((ut_dulint_get_high(table->id) == 0) 00582 && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { 00583 is_sys_table = TRUE; 00584 } else { 00585 is_sys_table = FALSE; 00586 } 00587 00588 mtr_start(&mtr); 00589 00590 sys_indexes = dict_table_get_low("SYS_INDEXES"); 00591 sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes); 00592 ut_a(!dict_table_is_comp(sys_indexes)); 00593 00594 tuple = dtuple_create(heap, 1); 00595 dfield = dtuple_get_nth_field(tuple, 0); 00596 00597 buf = mem_heap_alloc(heap, 8); 00598 mach_write_to_8(buf, table->id); 00599 00600 dfield_set_data(dfield, buf, 8); 00601 dict_index_copy_types(tuple, sys_index, 1); 00602 00603 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 00604 BTR_SEARCH_LEAF, &pcur, &mtr); 00605 for (;;) { 00606 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 00607 00608 break; 00609 } 00610 00611 rec = btr_pcur_get_rec(&pcur); 00612 00613 field = rec_get_nth_field_old(rec, 0, &len); 00614 ut_ad(len == 8); 00615 00616 if (ut_memcmp(buf, field, len) != 0) { 00617 break; 00618 } 00619 00620 if (rec_get_deleted_flag(rec, 0)) { 00621 dict_load_report_deleted_index(table->name, 00622 ULINT_UNDEFINED); 00623 00624 btr_pcur_close(&pcur); 00625 mtr_commit(&mtr); 00626 00627 return(FALSE); 00628 } 00629 00630 field = rec_get_nth_field_old(rec, 1, &len); 00631 ut_ad(len == 8); 00632 id = mach_read_from_8(field); 00633 00634 ut_a(0 == ut_strcmp("NAME", 00635 dict_field_get_col( 00636 dict_index_get_nth_field(sys_index, 4))->name)); 00637 00638 field = rec_get_nth_field_old(rec, 4, &name_len); 00639 name_buf = mem_heap_strdupl(heap, (char*) field, name_len); 00640 00641 field = rec_get_nth_field_old(rec, 5, &len); 00642 n_fields = mach_read_from_4(field); 00643 00644 field = rec_get_nth_field_old(rec, 6, &len); 00645 type = mach_read_from_4(field); 00646 00647 field = rec_get_nth_field_old(rec, 7, &len); 00648 space = mach_read_from_4(field); 00649 00650 ut_a(0 == ut_strcmp("PAGE_NO", 00651 dict_field_get_col( 00652 dict_index_get_nth_field(sys_index, 8))->name)); 00653 00654 field = rec_get_nth_field_old(rec, 8, &len); 00655 page_no = mach_read_from_4(field); 00656 00657 if (page_no == FIL_NULL) { 00658 00659 fprintf(stderr, 00660 "InnoDB: Error: trying to load index %s for table %s\n" 00661 "InnoDB: but the index tree has been freed!\n", 00662 name_buf, table->name); 00663 00664 btr_pcur_close(&pcur); 00665 mtr_commit(&mtr); 00666 00667 return(FALSE); 00668 } 00669 00670 if ((type & DICT_CLUSTERED) == 0 00671 && NULL == dict_table_get_first_index(table)) { 00672 00673 fprintf(stderr, 00674 "InnoDB: Error: trying to load index %s for table %s\n" 00675 "InnoDB: but the first index is not clustered!\n", 00676 name_buf, table->name); 00677 00678 btr_pcur_close(&pcur); 00679 mtr_commit(&mtr); 00680 00681 return(FALSE); 00682 } 00683 00684 if (is_sys_table 00685 && ((type & DICT_CLUSTERED) 00686 || ((table == dict_sys->sys_tables) 00687 && (name_len == (sizeof "ID_IND") - 1) 00688 && (0 == ut_memcmp(name_buf, "ID_IND", 00689 name_len))))) { 00690 00691 /* The index was created in memory already at booting 00692 of the database server */ 00693 } else { 00694 index = dict_mem_index_create(table->name, name_buf, 00695 space, type, n_fields); 00696 index->id = id; 00697 00698 dict_load_fields(table, index, heap); 00699 dict_index_add_to_cache(table, index, page_no); 00700 } 00701 00702 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00703 } 00704 00705 btr_pcur_close(&pcur); 00706 mtr_commit(&mtr); 00707 00708 return(TRUE); 00709 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void dict_load_report_deleted_index | ( | const char * | name, | |
| ulint | field | |||
| ) | [static] |
Definition at line 430 of file dict0load.c.
Referenced by dict_load_fields(), and dict_load_indexes().
00432 : table name */ 00433 ulint field) /* in: index field, or ULINT_UNDEFINED */ 00434 { 00435 fprintf(stderr, "InnoDB: Error: data dictionary entry" 00436 " for table %s is corrupt!\n", name); 00437 if (field != ULINT_UNDEFINED) { 00438 fprintf(stderr, 00439 "InnoDB: Index field %lu is delete marked.\n", field); 00440 } else { 00441 fputs("InnoDB: An index is delete marked.\n", stderr); 00442 } 00443 }
Here is the caller graph for this function:

| void dict_load_sys_table | ( | dict_table_t * | table | ) |
Definition at line 988 of file dict0load.c.
References dict_load_indexes(), dict_sys, mem_heap_create, mem_heap_free, dict_sys_struct::mutex, and ut_ad.
Referenced by dict_boot().
00990 : system table */ 00991 { 00992 mem_heap_t* heap; 00993 00994 #ifdef UNIV_SYNC_DEBUG 00995 ut_ad(mutex_own(&(dict_sys->mutex))); 00996 #endif /* UNIV_SYNC_DEBUG */ 00997 00998 heap = mem_heap_create(1000); 00999 01000 dict_load_indexes(table, heap); 01001 01002 mem_heap_free(heap); 01003 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_table_t* dict_load_table | ( | const char * | name | ) |
Definition at line 719 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, dfield_set_data(), dict_field_get_col(), dict_index_copy_types(), dict_index_get_nth_field(), dict_load_columns(), dict_load_foreigns(), dict_load_indexes(), dict_mem_table_create(), dict_sys, dict_table_add_to_cache(), dict_table_get_low(), dict_table_is_comp(), DICT_TABLE_ORDINARY, DICT_TF_COMPACT, dtuple_create(), dtuple_get_nth_field(), err, FALSE, fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), flags, dict_table_struct::ibd_file_missing, dict_table_struct::id, dict_table_struct::indexes, mach_read_from_4(), mach_read_from_8(), mem_heap_create, mem_heap_free, mtr_commit(), mtr_start(), dict_sys_struct::mutex, dict_table_struct::name, NULL, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), TRUE, ut_a, ut_ad, UT_LIST_GET_FIRST, ut_memcmp(), ut_print_timestamp(), ut_strcmp(), and ut_strlen().
Referenced by dict_load_table_on_id(), and row_drop_table_for_mysql().
00721 : table, NULL if does not exist; 00722 if the table is stored in an .ibd file, 00723 but the file does not exist, 00724 then we set the ibd_file_missing flag TRUE 00725 in the table object we return */ 00726 const char* name) /* in: table name in the 00727 databasename/tablename format */ 00728 { 00729 ibool ibd_file_missing = FALSE; 00730 dict_table_t* table; 00731 dict_table_t* sys_tables; 00732 btr_pcur_t pcur; 00733 dict_index_t* sys_index; 00734 dtuple_t* tuple; 00735 mem_heap_t* heap; 00736 dfield_t* dfield; 00737 rec_t* rec; 00738 byte* field; 00739 ulint len; 00740 ulint space; 00741 ulint n_cols; 00742 ulint flags; 00743 ulint err; 00744 mtr_t mtr; 00745 00746 #ifdef UNIV_SYNC_DEBUG 00747 ut_ad(mutex_own(&(dict_sys->mutex))); 00748 #endif /* UNIV_SYNC_DEBUG */ 00749 00750 heap = mem_heap_create(1000); 00751 00752 mtr_start(&mtr); 00753 00754 sys_tables = dict_table_get_low("SYS_TABLES"); 00755 sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); 00756 ut_a(!dict_table_is_comp(sys_tables)); 00757 00758 tuple = dtuple_create(heap, 1); 00759 dfield = dtuple_get_nth_field(tuple, 0); 00760 00761 dfield_set_data(dfield, name, ut_strlen(name)); 00762 dict_index_copy_types(tuple, sys_index, 1); 00763 00764 btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, 00765 BTR_SEARCH_LEAF, &pcur, &mtr); 00766 rec = btr_pcur_get_rec(&pcur); 00767 00768 if (!btr_pcur_is_on_user_rec(&pcur, &mtr) 00769 || rec_get_deleted_flag(rec, 0)) { 00770 /* Not found */ 00771 err_exit: 00772 btr_pcur_close(&pcur); 00773 mtr_commit(&mtr); 00774 mem_heap_free(heap); 00775 00776 return(NULL); 00777 } 00778 00779 field = rec_get_nth_field_old(rec, 0, &len); 00780 00781 /* Check if the table name in record is the searched one */ 00782 if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) { 00783 00784 goto err_exit; 00785 } 00786 00787 ut_a(0 == ut_strcmp("SPACE", 00788 dict_field_get_col( 00789 dict_index_get_nth_field(sys_index, 9))->name)); 00790 00791 field = rec_get_nth_field_old(rec, 9, &len); 00792 space = mach_read_from_4(field); 00793 00794 /* Check if the tablespace exists and has the right name */ 00795 if (space != 0) { 00796 if (fil_space_for_table_exists_in_mem(space, name, FALSE, 00797 FALSE, FALSE)) { 00798 /* Ok; (if we did a crash recovery then the tablespace 00799 can already be in the memory cache) */ 00800 } else { 00801 /* In >= 4.1.9, InnoDB scans the data dictionary also 00802 at a normal mysqld startup. It is an error if the 00803 space object does not exist in memory. */ 00804 00805 ut_print_timestamp(stderr); 00806 fprintf(stderr, 00807 " InnoDB: error: space object of table %s,\n" 00808 "InnoDB: space id %lu did not exist in memory. Retrying an open.\n", 00809 name, (ulong)space); 00810 /* Try to open the tablespace */ 00811 if (!fil_open_single_table_tablespace(TRUE, 00812 space, name)) { 00813 /* We failed to find a sensible tablespace 00814 file */ 00815 00816 ibd_file_missing = TRUE; 00817 } 00818 } 00819 } 00820 00821 ut_a(0 == ut_strcmp("N_COLS", 00822 dict_field_get_col( 00823 dict_index_get_nth_field(sys_index, 4))->name)); 00824 00825 field = rec_get_nth_field_old(rec, 4, &len); 00826 n_cols = mach_read_from_4(field); 00827 00828 flags = 0; 00829 00830 /* The high-order bit of N_COLS is the "compact format" flag. */ 00831 if (n_cols & 0x80000000UL) { 00832 flags |= DICT_TF_COMPACT; 00833 } 00834 00835 table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL, 00836 flags); 00837 00838 table->ibd_file_missing = ibd_file_missing; 00839 00840 ut_a(0 == ut_strcmp("ID", 00841 dict_field_get_col( 00842 dict_index_get_nth_field(sys_index, 3))->name)); 00843 00844 field = rec_get_nth_field_old(rec, 3, &len); 00845 table->id = mach_read_from_8(field); 00846 00847 field = rec_get_nth_field_old(rec, 5, &len); 00848 if (UNIV_UNLIKELY(mach_read_from_4(field) != DICT_TABLE_ORDINARY)) { 00849 ut_print_timestamp(stderr); 00850 fprintf(stderr, 00851 " InnoDB: table %s: unknown table type %lu\n", 00852 name, (ulong) mach_read_from_4(field)); 00853 goto err_exit; 00854 } 00855 00856 btr_pcur_close(&pcur); 00857 mtr_commit(&mtr); 00858 00859 dict_load_columns(table, heap); 00860 00861 dict_table_add_to_cache(table); 00862 00863 dict_load_indexes(table, heap); 00864 00865 err = dict_load_foreigns(table->name, TRUE); 00866 /* 00867 if (err != DB_SUCCESS) { 00868 00869 mutex_enter(&dict_foreign_err_mutex); 00870 00871 ut_print_timestamp(stderr); 00872 00873 fprintf(stderr, 00874 " InnoDB: Error: could not make a foreign key definition to match\n" 00875 "InnoDB: the foreign key table or the referenced table!\n" 00876 "InnoDB: The data dictionary of InnoDB is corrupt. You may need to drop\n" 00877 "InnoDB: and recreate the foreign key table or the referenced table.\n" 00878 "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" 00879 "InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf); 00880 00881 mutex_exit(&dict_foreign_err_mutex); 00882 } 00883 */ 00884 mem_heap_free(heap); 00885 00886 return(table); 00887 }
Here is the call graph for this function:

Here is the caller graph for this function:

| dict_table_t* dict_load_table_on_id | ( | dulint | table_id | ) |
Definition at line 893 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_open_on_user_rec(), BTR_SEARCH_LEAF, dfield_set_data(), dict_index_copy_types(), dict_load_table(), dict_sys, dict_table_get_first_index(), dict_table_get_next_index(), dict_table_is_comp(), dtuple_create(), dtuple_get_nth_field(), mach_read_from_8(), mach_write_to_8(), mem_heap_create, mem_heap_free, mem_heap_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, NULL, PAGE_CUR_GE, rec_get_deleted_flag(), rec_get_nth_field_old(), dict_sys_struct::sys_tables, ut_a, ut_ad, and ut_dulint_cmp().
00895 : table; NULL if table does not exist */ 00896 dulint table_id) /* in: table id */ 00897 { 00898 byte id_buf[8]; 00899 btr_pcur_t pcur; 00900 mem_heap_t* heap; 00901 dtuple_t* tuple; 00902 dfield_t* dfield; 00903 dict_index_t* sys_table_ids; 00904 dict_table_t* sys_tables; 00905 rec_t* rec; 00906 byte* field; 00907 ulint len; 00908 dict_table_t* table; 00909 mtr_t mtr; 00910 00911 #ifdef UNIV_SYNC_DEBUG 00912 ut_ad(mutex_own(&(dict_sys->mutex))); 00913 #endif /* UNIV_SYNC_DEBUG */ 00914 00915 /* NOTE that the operation of this function is protected by 00916 the dictionary mutex, and therefore no deadlocks can occur 00917 with other dictionary operations. */ 00918 00919 mtr_start(&mtr); 00920 /*---------------------------------------------------*/ 00921 /* Get the secondary index based on ID for table SYS_TABLES */ 00922 sys_tables = dict_sys->sys_tables; 00923 sys_table_ids = dict_table_get_next_index( 00924 dict_table_get_first_index(sys_tables)); 00925 ut_a(!dict_table_is_comp(sys_tables)); 00926 heap = mem_heap_create(256); 00927 00928 tuple = dtuple_create(heap, 1); 00929 dfield = dtuple_get_nth_field(tuple, 0); 00930 00931 /* Write the table id in byte format to id_buf */ 00932 mach_write_to_8(id_buf, table_id); 00933 00934 dfield_set_data(dfield, id_buf, 8); 00935 dict_index_copy_types(tuple, sys_table_ids, 1); 00936 00937 btr_pcur_open_on_user_rec(sys_table_ids, tuple, PAGE_CUR_GE, 00938 BTR_SEARCH_LEAF, &pcur, &mtr); 00939 rec = btr_pcur_get_rec(&pcur); 00940 00941 if (!btr_pcur_is_on_user_rec(&pcur, &mtr) 00942 || rec_get_deleted_flag(rec, 0)) { 00943 /* Not found */ 00944 00945 btr_pcur_close(&pcur); 00946 mtr_commit(&mtr); 00947 mem_heap_free(heap); 00948 00949 return(NULL); 00950 } 00951 00952 /*---------------------------------------------------*/ 00953 /* Now we have the record in the secondary index containing the 00954 table ID and NAME */ 00955 00956 rec = btr_pcur_get_rec(&pcur); 00957 field = rec_get_nth_field_old(rec, 0, &len); 00958 ut_ad(len == 8); 00959 00960 /* Check if the table id in record is the one searched for */ 00961 if (ut_dulint_cmp(table_id, mach_read_from_8(field)) != 0) { 00962 00963 btr_pcur_close(&pcur); 00964 mtr_commit(&mtr); 00965 mem_heap_free(heap); 00966 00967 return(NULL); 00968 } 00969 00970 /* Now we get the table name from the record */ 00971 field = rec_get_nth_field_old(rec, 1, &len); 00972 /* Load the table definition to memory */ 00973 table = dict_load_table(mem_heap_strdupl(heap, (char*) field, len)); 00974 00975 btr_pcur_close(&pcur); 00976 mtr_commit(&mtr); 00977 mem_heap_free(heap); 00978 00979 return(table); 00980 }
Here is the call graph for this function:

| void dict_print | ( | void | ) |
Definition at line 120 of file dict0load.c.
References btr_pcur_close(), btr_pcur_get_rec(), btr_pcur_is_on_user_rec(), btr_pcur_move_to_next_user_rec(), btr_pcur_open_at_index_side(), btr_pcur_restore_position(), btr_pcur_store_position(), BTR_SEARCH_LEAF, dict_sys, dict_table_get_first_index(), dict_table_get_low(), dict_table_print_low(), dict_update_statistics_low(), dict_table_struct::indexes, kernel_mutex, mem_free, mem_strdupl(), mtr_commit(), mtr_start(), dict_sys_struct::mutex, mutex_enter, mutex_exit(), NULL, rec_get_deleted_flag(), rec_get_nth_field_old(), srv_fatal_semaphore_wait_threshold, TRUE, UT_LIST_GET_FIRST, and ut_print_namel().
Referenced by srv_lock_timeout_and_monitor_thread().
00122 { 00123 dict_table_t* sys_tables; 00124 dict_index_t* sys_index; 00125 dict_table_t* table; 00126 btr_pcur_t pcur; 00127 rec_t* rec; 00128 byte* field; 00129 ulint len; 00130 mtr_t mtr; 00131 00132 /* Enlarge the fatal semaphore wait timeout during the InnoDB table 00133 monitor printout */ 00134 00135 mutex_enter(&kernel_mutex); 00136 srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */ 00137 mutex_exit(&kernel_mutex); 00138 00139 mutex_enter(&(dict_sys->mutex)); 00140 00141 mtr_start(&mtr); 00142 00143 sys_tables = dict_table_get_low("SYS_TABLES"); 00144 sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); 00145 00146 btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur, 00147 TRUE, &mtr); 00148 loop: 00149 btr_pcur_move_to_next_user_rec(&pcur, &mtr); 00150 00151 rec = btr_pcur_get_rec(&pcur); 00152 00153 if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { 00154 /* end of index */ 00155 00156 btr_pcur_close(&pcur); 00157 mtr_commit(&mtr); 00158 00159 mutex_exit(&(dict_sys->mutex)); 00160 00161 /* Restore the fatal semaphore wait timeout */ 00162 00163 mutex_enter(&kernel_mutex); 00164 srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */ 00165 mutex_exit(&kernel_mutex); 00166 00167 return; 00168 } 00169 00170 field = rec_get_nth_field_old(rec, 0, &len); 00171 00172 if (!rec_get_deleted_flag(rec, 0)) { 00173 00174 /* We found one */ 00175 00176 char* table_name = mem_strdupl((char*) field, len); 00177 00178 btr_pcur_store_position(&pcur, &mtr); 00179 00180 mtr_commit(&mtr); 00181 00182 table = dict_table_get_low(table_name); 00183 mem_free(table_name); 00184 00185 if (table == NULL) { 00186 fputs("InnoDB: Failed to load table ", stderr); 00187 ut_print_namel(stderr, NULL, TRUE, (char*) field, len); 00188 putc('\n', stderr); 00189 } else { 00190 /* The table definition was corrupt if there 00191 is no index */ 00192 00193 if (dict_table_get_first_index(table)) { 00194 dict_update_statistics_low(table, TRUE); 00195 } 00196 00197 dict_table_print_low(table); 00198 } 00199 00200 mtr_start(&mtr); 00201 00202 btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); 00203 } 00204 00205 goto loop; 00206 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

