📄 dict0load.c
字号:
btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; ulint pos_and_prefix_len; ulint prefix_len; rec_t* rec; byte* field; ulint len; byte* buf; ulint i; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ UT_NOT_USED(table); mtr_start(&mtr); sys_fields = dict_table_get_low("SYS_FIELDS"); sys_index = UT_LIST_GET_FIRST(sys_fields->indexes); ut_a(!sys_fields->comp); tuple = dtuple_create(heap, 1); dfield = dtuple_get_nth_field(tuple, 0); buf = mem_heap_alloc(heap, 8); mach_write_to_8(buf, index->id); dfield_set_data(dfield, buf, 8); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); for (i = 0; i < index->n_fields; i++) { rec = btr_pcur_get_rec(&pcur); ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr)); if (rec_get_deleted_flag(rec, sys_fields->comp)) { dict_load_report_deleted_index(table->name, i); } field = rec_get_nth_field_old(rec, 0, &len); ut_ad(len == 8); ut_a(ut_memcmp(buf, field, len) == 0); field = rec_get_nth_field_old(rec, 1, &len); ut_a(len == 4); /* The next field stores the field position in the index and a possible column prefix length if the index field does not contain the whole column. The storage format is like this: if there is at least one prefix field in the index, then the HIGH 2 bytes contain the field number (== i) and the low 2 bytes the prefix length for the field. Otherwise the field number (== i) is contained in the 2 LOW bytes. */ pos_and_prefix_len = mach_read_from_4(field); ut_a((pos_and_prefix_len & 0xFFFFUL) == i || (pos_and_prefix_len & 0xFFFF0000UL) == (i << 16)); if ((i == 0 && pos_and_prefix_len > 0) || (pos_and_prefix_len & 0xFFFF0000UL) > 0) { prefix_len = pos_and_prefix_len & 0xFFFFUL; } else { prefix_len = 0; } ut_a(0 == ut_strcmp("COL_NAME", dict_field_get_col( dict_index_get_nth_field(sys_index, 4))->name)); field = rec_get_nth_field_old(rec, 4, &len); dict_mem_index_add_field(index, mem_heap_strdupl(heap, (char*) field, len), 0, prefix_len); btr_pcur_move_to_next_user_rec(&pcur, &mtr); } btr_pcur_close(&pcur); mtr_commit(&mtr);}/************************************************************************Loads definitions for table indexes. Adds them to the data dictionarycache. */staticibooldict_load_indexes(/*==============*/ /* out: TRUE if ok, FALSE if corruption of dictionary table */ dict_table_t* table, /* in: table */ mem_heap_t* heap) /* in: memory heap for temporary storage */{ dict_table_t* sys_indexes; dict_index_t* sys_index; dict_index_t* index; btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; rec_t* rec; byte* field; ulint len; ulint name_len; char* name_buf; ulint type; ulint space; ulint page_no; ulint n_fields; byte* buf; ibool is_sys_table; dulint id; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ if ((ut_dulint_get_high(table->id) == 0) && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) { is_sys_table = TRUE; } else { is_sys_table = FALSE; } mtr_start(&mtr); sys_indexes = dict_table_get_low("SYS_INDEXES"); sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes); ut_a(!sys_indexes->comp); tuple = dtuple_create(heap, 1); dfield = dtuple_get_nth_field(tuple, 0); buf = mem_heap_alloc(heap, 8); mach_write_to_8(buf, table->id); dfield_set_data(dfield, buf, 8); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); for (;;) { if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { break; } rec = btr_pcur_get_rec(&pcur); field = rec_get_nth_field_old(rec, 0, &len); ut_ad(len == 8); if (ut_memcmp(buf, field, len) != 0) { break; } if (rec_get_deleted_flag(rec, table->comp)) { dict_load_report_deleted_index(table->name, ULINT_UNDEFINED); btr_pcur_close(&pcur); mtr_commit(&mtr); return(FALSE); } field = rec_get_nth_field_old(rec, 1, &len); ut_ad(len == 8); id = mach_read_from_8(field); ut_a(0 == ut_strcmp("NAME", dict_field_get_col( dict_index_get_nth_field(sys_index, 4))->name)); field = rec_get_nth_field_old(rec, 4, &name_len); name_buf = mem_heap_strdupl(heap, (char*) field, name_len); field = rec_get_nth_field_old(rec, 5, &len); n_fields = mach_read_from_4(field); field = rec_get_nth_field_old(rec, 6, &len); type = mach_read_from_4(field); field = rec_get_nth_field_old(rec, 7, &len); space = mach_read_from_4(field); ut_a(0 == ut_strcmp("PAGE_NO", dict_field_get_col( dict_index_get_nth_field(sys_index, 8))->name)); field = rec_get_nth_field_old(rec, 8, &len); page_no = mach_read_from_4(field); if (page_no == FIL_NULL) { fprintf(stderr, "InnoDB: Error: trying to load index %s for table %s\n" "InnoDB: but the index tree has been freed!\n", name_buf, table->name); btr_pcur_close(&pcur); mtr_commit(&mtr); return(FALSE); } if ((type & DICT_CLUSTERED) == 0 && NULL == dict_table_get_first_index(table)) { fprintf(stderr, "InnoDB: Error: trying to load index %s for table %s\n" "InnoDB: but the first index is not clustered!\n", name_buf, table->name); btr_pcur_close(&pcur); mtr_commit(&mtr); return(FALSE); } if (is_sys_table && ((type & DICT_CLUSTERED) || ((table == dict_sys->sys_tables) && (name_len == (sizeof "ID_IND") - 1) && (0 == ut_memcmp(name_buf, "ID_IND", name_len))))) { /* The index was created in memory already at booting of the database server */ } else { index = dict_mem_index_create(table->name, name_buf, space, type, n_fields); index->id = id; dict_load_fields(table, index, heap); dict_index_add_to_cache(table, index, page_no); } btr_pcur_move_to_next_user_rec(&pcur, &mtr); } btr_pcur_close(&pcur); mtr_commit(&mtr); return(TRUE);}/************************************************************************Loads a table definition and also all its index definitions, and alsothe cluster definition if the table is a member in a cluster. Also loadsall foreign key constraints where the foreign key is in the table or wherea foreign key references columns in this table. Adds all these to the datadictionary cache. */dict_table_t*dict_load_table(/*============*/ /* out: table, NULL if does not exist; if the table is stored in an .ibd file, but the file does not exist, then we set the ibd_file_missing flag TRUE in the table object we return */ const char* name) /* in: table name in the databasename/tablename format */{ ibool ibd_file_missing = FALSE; dict_table_t* table; dict_table_t* sys_tables; btr_pcur_t pcur; dict_index_t* sys_index; dtuple_t* tuple; mem_heap_t* heap; dfield_t* dfield; rec_t* rec; byte* field; ulint len; ulint space; ulint n_cols; ulint err; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1000); mtr_start(&mtr); sys_tables = dict_table_get_low("SYS_TABLES"); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); ut_a(!sys_tables->comp); tuple = dtuple_create(heap, 1); dfield = dtuple_get_nth_field(tuple, 0); dfield_set_data(dfield, name, ut_strlen(name)); dict_index_copy_types(tuple, sys_index, 1); btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); rec = btr_pcur_get_rec(&pcur); if (!btr_pcur_is_on_user_rec(&pcur, &mtr) || rec_get_deleted_flag(rec, sys_tables->comp)) { /* Not found */ btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); return(NULL); } field = rec_get_nth_field_old(rec, 0, &len); /* Check if the table name in record is the searched one */ if (len != ut_strlen(name) || ut_memcmp(name, field, len) != 0) { btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); return(NULL); } ut_a(0 == ut_strcmp("SPACE", dict_field_get_col( dict_index_get_nth_field(sys_index, 9))->name)); field = rec_get_nth_field_old(rec, 9, &len); space = mach_read_from_4(field); /* Check if the tablespace exists and has the right name */ if (space != 0) { if (fil_space_for_table_exists_in_mem(space, name, FALSE, FALSE, FALSE)) { /* Ok; (if we did a crash recovery then the tablespace can already be in the memory cache) */ } else { /* In >= 4.1.9, InnoDB scans the data dictionary also at a normal mysqld startup. It is an error if the space object does not exist in memory. */ ut_print_timestamp(stderr); fprintf(stderr," InnoDB: error: space object of table %s,\n""InnoDB: space id %lu did not exist in memory. Retrying an open.\n", name, (ulong)space); /* Try to open the tablespace */ if (!fil_open_single_table_tablespace(TRUE, space, name)) { /* We failed to find a sensible tablespace file */ ibd_file_missing = TRUE; } } } ut_a(0 == ut_strcmp("N_COLS", dict_field_get_col( dict_index_get_nth_field(sys_index, 4))->name)); field = rec_get_nth_field_old(rec, 4, &len); n_cols = mach_read_from_4(field); /* The high-order bit of N_COLS is the "compact format" flag. */ table = dict_mem_table_create(name, space, n_cols & ~0x80000000UL, !!(n_cols & 0x80000000UL)); table->ibd_file_missing = ibd_file_missing; ut_a(0 == ut_strcmp("ID", dict_field_get_col( dict_index_get_nth_field(sys_index, 3))->name)); field = rec_get_nth_field_old(rec, 3, &len); table->id = mach_read_from_8(field); field = rec_get_nth_field_old(rec, 5, &len); table->type = mach_read_from_4(field); if (table->type == DICT_TABLE_CLUSTER_MEMBER) { ut_error;#if 0 /* clustered tables have not been implemented yet */ field = rec_get_nth_field_old(rec, 6, &len); table->mix_id = mach_read_from_8(field); field = rec_get_nth_field_old(rec, 8, &len); table->cluster_name = mem_heap_strdupl(heap, (char*) field, len);#endif } if ((table->type == DICT_TABLE_CLUSTER) || (table->type == DICT_TABLE_CLUSTER_MEMBER)) { field = rec_get_nth_field_old(rec, 7, &len); ut_a(len == 4); table->mix_len = mach_read_from_4(field); } btr_pcur_close(&pcur); mtr_commit(&mtr); if (table->type == DICT_TABLE_CLUSTER_MEMBER) { /* Load the cluster table definition if not yet in memory cache */ dict_table_get_low(table->cluster_name); } dict_load_columns(table, heap); dict_table_add_to_cache(table); dict_load_indexes(table, heap); err = dict_load_foreigns(table->name, TRUE);/* if (err != DB_SUCCESS) { mutex_enter(&dict_foreign_err_mutex); ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Error: could not make a foreign key definition to match\n""InnoDB: the foreign key table or the referenced table!\n""InnoDB: The data dictionary of InnoDB is corrupt. You may need to drop\n""InnoDB: and recreate the foreign key table or the referenced table.\n""InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n""InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf); mutex_exit(&dict_foreign_err_mutex); }*/ mem_heap_free(heap); return(table);}/***************************************************************************Loads a table object based on the table id. */dict_table_t*dict_load_table_on_id(/*==================*/ /* out: table; NULL if table does not exist */ dulint table_id) /* in: table id */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -