📄 dict0dict.c
字号:
ut_fold_string(table->name), table); old_name = mem_heap_strdup(table->heap, table->name); table->name = mem_heap_strdup(table->heap, new_name); /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); dict_sys->size += (mem_heap_get_size(table->heap) - old_size); /* Update the table_name field in indexes */ index = dict_table_get_first_index(table); while (index != NULL) { index->table_name = table->name; index = dict_table_get_next_index(index); } if (!rename_also_foreigns) { /* In ALTER TABLE we think of the rename table operation in the direction table -> temporary table (#sql...) as dropping the table with the old name and creating a new with the new name. Thus we kind of drop the constraints from the dictionary cache here. The foreign key constraints will be inherited to the new table from the system tables through a call of dict_load_foreigns. */ /* Remove the foreign constraints from the cache */ foreign = UT_LIST_GET_LAST(table->foreign_list); while (foreign != NULL) { dict_foreign_remove_from_cache(foreign); foreign = UT_LIST_GET_LAST(table->foreign_list); } /* Reset table field in referencing constraints */ foreign = UT_LIST_GET_FIRST(table->referenced_list); while (foreign != NULL) { foreign->referenced_table = NULL; foreign->referenced_index = NULL; foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } /* Make the list of referencing constraints empty */ UT_LIST_INIT(table->referenced_list); return(TRUE); } /* Update the table name fields in foreign constraints, and update also the constraint id of new format >= 4.0.18 constraints. Note that at this point we have already changed table->name to the new name. */ foreign = UT_LIST_GET_FIRST(table->foreign_list); while (foreign != NULL) { if (ut_strlen(foreign->foreign_table_name) < ut_strlen(table->name)) { /* Allocate a longer name buffer; TODO: store buf len to save memory */ foreign->foreign_table_name = mem_heap_alloc( foreign->heap, ut_strlen(table->name) + 1); } strcpy(foreign->foreign_table_name, table->name); if (strchr(foreign->id, '/')) { ulint db_len; char* old_id; /* This is a >= 4.0.18 format id */ old_id = mem_strdup(foreign->id); if (ut_strlen(foreign->id) > ut_strlen(old_name) + ((sizeof dict_ibfk) - 1) && 0 == ut_memcmp(foreign->id, old_name, ut_strlen(old_name)) && 0 == ut_memcmp( foreign->id + ut_strlen(old_name), dict_ibfk, (sizeof dict_ibfk) - 1)) { /* This is a generated >= 4.0.18 format id */ if (ut_strlen(table->name) > ut_strlen(old_name)) { foreign->id = mem_heap_alloc( foreign->heap, ut_strlen(table->name) + ut_strlen(old_id) + 1); } /* Replace the prefix 'databasename/tablename' with the new names */ strcpy(foreign->id, table->name); strcat(foreign->id, old_id + ut_strlen(old_name)); } else { /* This is a >= 4.0.18 format id where the user gave the id name */ db_len = dict_get_db_name_len(table->name) + 1; if (dict_get_db_name_len(table->name) > dict_get_db_name_len(foreign->id)) { foreign->id = mem_heap_alloc( foreign->heap, db_len + ut_strlen(old_id) + 1); } /* Replace the database prefix in id with the one from table->name */ ut_memcpy(foreign->id, table->name, db_len); strcpy(foreign->id + db_len, dict_remove_db_name(old_id)); } mem_free(old_id); } foreign = UT_LIST_GET_NEXT(foreign_list, foreign); } foreign = UT_LIST_GET_FIRST(table->referenced_list); while (foreign != NULL) { if (ut_strlen(foreign->referenced_table_name) < ut_strlen(table->name)) { /* Allocate a longer name buffer; TODO: store buf len to save memory */ foreign->referenced_table_name = mem_heap_alloc( foreign->heap, ut_strlen(table->name) + 1); } strcpy(foreign->referenced_table_name, table->name); foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } return(TRUE);}/**************************************************************************Change the id of a table object in the dictionary cache. This is used inDISCARD TABLESPACE. */voiddict_table_change_id_in_cache(/*==========================*/ dict_table_t* table, /* in: table object already in cache */ dulint new_id) /* in: new id to set */{ ut_ad(table);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); /* Remove the table from the hash table of id's */ HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, ut_fold_dulint(table->id), table); table->id = new_id; /* Add the table back to the hash table */ HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, ut_fold_dulint(table->id), table);}/**************************************************************************Removes a table object from the dictionary cache. */voiddict_table_remove_from_cache(/*=========================*/ dict_table_t* table) /* in, own: table */{ dict_foreign_t* foreign; dict_index_t* index; ulint size; ulint i; ut_ad(table);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);#if 0 fputs("Removing table ", stderr); ut_print_name(stderr, table->name, ULINT_UNDEFINED); fputs(" from dictionary cache\n", stderr);#endif /* Remove the foreign constraints from the cache */ foreign = UT_LIST_GET_LAST(table->foreign_list); while (foreign != NULL) { dict_foreign_remove_from_cache(foreign); foreign = UT_LIST_GET_LAST(table->foreign_list); } /* Reset table field in referencing constraints */ foreign = UT_LIST_GET_FIRST(table->referenced_list); while (foreign != NULL) { foreign->referenced_table = NULL; foreign->referenced_index = NULL; foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } /* Remove the indexes from the cache */ index = UT_LIST_GET_LAST(table->indexes); while (index != NULL) { dict_index_remove_from_cache(table, index); index = UT_LIST_GET_LAST(table->indexes); } /* Remove the columns of the table from the cache */ for (i = 0; i < table->n_cols; i++) { dict_col_remove_from_cache(table, dict_table_get_nth_col(table, i)); } /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, ut_fold_string(table->name), table); HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash, ut_fold_dulint(table->id), table); /* Remove table from LRU list of tables */ UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); mutex_free(&(table->autoinc_mutex)); size = mem_heap_get_size(table->heap); ut_ad(dict_sys->size >= size); dict_sys->size -= size; mem_heap_free(table->heap);}/**************************************************************************Frees tables from the end of table_LRU if the dictionary cache occupiestoo much space. Currently not used! */voiddict_table_LRU_trim(void)/*=====================*/{ dict_table_t* table; dict_table_t* prev_table; ut_error;#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ table = UT_LIST_GET_LAST(dict_sys->table_LRU); while (table && (dict_sys->size > buf_pool_get_max_size() / DICT_POOL_PER_VARYING)) { prev_table = UT_LIST_GET_PREV(table_LRU, table); if (table->mem_fix == 0) { dict_table_remove_from_cache(table); } table = prev_table; }}/**************************************************************************Adds a column to the data dictionary hash table. */staticvoiddict_col_add_to_cache(/*==================*/ dict_table_t* table, /* in: table */ dict_col_t* col) /* in: column */{ ulint fold; ut_ad(table && col);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); fold = ut_fold_ulint_pair(ut_fold_string(table->name), ut_fold_string(col->name)); /* Look for a column with same table name and column name: error */ { dict_col_t* col2; HASH_SEARCH(hash, dict_sys->col_hash, fold, col2, (ut_strcmp(col->name, col2->name) == 0) && (ut_strcmp((col2->table)->name, table->name) == 0)); ut_a(col2 == NULL); } HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);}/**************************************************************************Removes a column from the data dictionary hash table. */staticvoiddict_col_remove_from_cache(/*=======================*/ dict_table_t* table, /* in: table */ dict_col_t* col) /* in: column */{ ulint fold; ut_ad(table && col);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); fold = ut_fold_ulint_pair(ut_fold_string(table->name), ut_fold_string(col->name)); HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col);}/**************************************************************************Repositions a column in the data dictionary hash table when the table namechanges. */staticvoiddict_col_reposition_in_cache(/*=========================*/ dict_table_t* table, /* in: table */ dict_col_t* col, /* in: column */ const char* new_name) /* in: new table name */{ ulint fold; ut_ad(table && col);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); fold = ut_fold_ulint_pair(ut_fold_string(table->name), ut_fold_string(col->name)); HASH_DELETE(dict_col_t, hash, dict_sys->col_hash, fold, col); fold = ut_fold_ulint_pair(ut_fold_string(new_name), ut_fold_string(col->name)); HASH_INSERT(dict_col_t, hash, dict_sys->col_hash, fold, col);}/**************************************************************************Adds an index to the dictionary cache. */ibooldict_index_add_to_cache(/*====================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table on which the index is */ dict_index_t* index, /* in, own: index; NOTE! The index memory object is freed in this function! */ ulint page_no)/* in: root page number of the index */{ dict_index_t* new_index; dict_tree_t* tree; dict_table_t* cluster; dict_field_t* field; ulint n_ord; ibool success; ulint i; ut_ad(index);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(index->n_def == index->n_fields); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); ut_ad(mem_heap_validate(index->heap)); { dict_index_t* index2; index2 = UT_LIST_GET_FIRST(table->indexes); while (index2 != NULL) { ut_ad(ut_strcmp(index->name, index2->name) != 0); index2 = UT_LIST_GET_NEXT(indexes, index2); } ut_a(UT_LIST_GET_LEN(table->indexes) == 0 || (index->type & DICT_CLUSTERED) == 0); } success = dict_index_find_cols(table, index); if (!success) { dict_mem_index_free(index); return(FALSE); } /* Build the cache internal representation of the index, containing also the added system fields */ if (index->type & DICT_CLUSTERED) { new_index = dict_index_build_internal_clust(table, index); } else { new_index = dict_index_build_internal_non_clust(table, index); } new_index->search_info = btr_search_info_create(new_index->heap); /* Set the n_fields value in new_index to the actual defined number of fields in the cache internal representation */ new_index->n_fields = new_index->n_def; /* Add the new index as the last index for the table */ UT_LIST_ADD_LAST(indexes, table->indexes, new_index); new_index->table = table; new_index->table_name = table->name; /* Increment the ord_part counts in columns which are ordering */ if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) { n_ord = new_index->n_fields; } else { n_ord = dict_index_get_n_unique(new_index); } for (i = 0; i < n_ord; i++) { field = dict_index_get_nth_field(new_index, i); dict_field_get_col(field)->ord_part++; } if (table->type == DICT_TABLE_CLUSTER_MEMBER) { /* The index tree is found from the cluster object */ cluster = dict_table_get_low(table->cluster_name); tree = dict_index_get_tree( UT_LIST_GET_FIRST(cluster->indexes)); new_index->tree = tree; } else { /* Create an index tree memory object for the index */ tree = dict_tree_create(new_index, page_no); ut_ad(tree); new_index->tree = tree; } if (!UNIV_UNLIKELY(new_index->type & DICT_UNIVERSAL)) { new_index->stat_n_diff_key_vals = mem_heap_alloc(new_index->heap, (1 + dict_index_get_n_unique(new_index)) * sizeof(ib_longlong)); /* Give some sensible values to stat_n_... in case we do not calculate statistics quickly enough */ for (i = 0; i <= dict_index_get_n_unique(new_index); i++) { new_index->stat_n_diff_key_vals[i] = 100; } } /* Add the index to the list of indexes stored in the tree */ UT_LIST_ADD_LAST(tree_indexes, tree->tree_indexes, new_index); /* If the dictionary cache grows too big, trim the table LRU list */ dict_sys->size += mem_heap_get_size(new_index->heap); /* dict_table_LRU_trim(); */ dict_mem_index_free(index);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -