📄 dict0dict.c
字号:
col = dict_table_get_nth_col(index->table, n); if (index->type & DICT_CLUSTERED) { return(col->clust_pos); } n_fields = dict_index_get_n_fields(index); for (pos = 0; pos < n_fields; pos++) { field = dict_index_get_nth_field(index, pos); if (col == field->col && field->prefix_len == 0) { return(pos); } } return(ULINT_UNDEFINED);}/************************************************************************Returns TRUE if the index contains a column or a prefix of that column. */ibooldict_index_contains_col_or_prefix(/*==============================*/ /* out: TRUE if contains the column or its prefix */ dict_index_t* index, /* in: index */ ulint n) /* in: column number */{ dict_field_t* field; dict_col_t* col; ulint pos; ulint n_fields; ut_ad(index); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); if (index->type & DICT_CLUSTERED) { return(TRUE); } col = dict_table_get_nth_col(index->table, n); n_fields = dict_index_get_n_fields(index); for (pos = 0; pos < n_fields; pos++) { field = dict_index_get_nth_field(index, pos); if (col == field->col) { return(TRUE); } } return(FALSE);}/************************************************************************Looks for a matching field in an index. The column has to be the same. Thecolumn in index must be complete, or must contain a prefix longer than thecolumn in index2. That is, we must be able to construct the prefix in index2from the prefix in index. */ulintdict_index_get_nth_field_pos(/*=========================*/ /* out: position in internal representation of the index; if not contained, returns ULINT_UNDEFINED */ dict_index_t* index, /* in: index from which to search */ dict_index_t* index2, /* in: index */ ulint n) /* in: field number in index2 */{ dict_field_t* field; dict_field_t* field2; ulint n_fields; ulint pos; ut_ad(index); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); field2 = dict_index_get_nth_field(index2, n); n_fields = dict_index_get_n_fields(index); for (pos = 0; pos < n_fields; pos++) { field = dict_index_get_nth_field(index, pos); if (field->col == field2->col && (field->prefix_len == 0 || (field->prefix_len >= field2->prefix_len && field2->prefix_len != 0))) { return(pos); } } return(ULINT_UNDEFINED);}/**************************************************************************Returns a table object, based on table id, and memoryfixes it. */dict_table_t*dict_table_get_on_id(/*=================*/ /* out: table, NULL if does not exist */ dulint table_id, /* in: table id */ trx_t* trx) /* in: transaction handle */{ dict_table_t* table; if (ut_dulint_cmp(table_id, DICT_FIELDS_ID) <= 0 || trx->dict_operation_lock_mode == RW_X_LATCH) { /* It is a system table which will always exist in the table cache: we avoid acquiring the dictionary mutex, because if we are doing a rollback to handle an error in TABLE CREATE, for example, we already have the mutex! */#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ return(dict_table_get_on_id_low(table_id, trx)); } mutex_enter(&(dict_sys->mutex)); table = dict_table_get_on_id_low(table_id, trx); mutex_exit(&(dict_sys->mutex)); return(table);}/************************************************************************Looks for column n position in the clustered index. */ulintdict_table_get_nth_col_pos(/*=======================*/ /* out: position in internal representation of the clustered index */ dict_table_t* table, /* in: table */ ulint n) /* in: column number */{ return(dict_index_get_nth_col_pos(dict_table_get_first_index(table), n));}/************************************************************************Checks if a column is in the ordering columns of the clustered index of atable. Column prefixes are treated like whole columns. */ibooldict_table_col_in_clustered_key(/*============================*/ /* out: TRUE if the column, or its prefix, is in the clustered key */ dict_table_t* table, /* in: table */ ulint n) /* in: column number */{ dict_index_t* index; dict_field_t* field; dict_col_t* col; ulint pos; ulint n_fields; ut_ad(table); col = dict_table_get_nth_col(table, n); index = dict_table_get_first_index(table); n_fields = dict_index_get_n_unique(index); for (pos = 0; pos < n_fields; pos++) { field = dict_index_get_nth_field(index, pos); if (col == field->col) { return(TRUE); } } return(FALSE);}/**************************************************************************Inits the data dictionary module. */voiddict_init(void)/*===========*/{ dict_sys = mem_alloc(sizeof(dict_sys_t)); mutex_create(&(dict_sys->mutex)); mutex_set_level(&(dict_sys->mutex), SYNC_DICT); dict_sys->table_hash = hash_create(buf_pool_get_max_size() / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); dict_sys->table_id_hash = hash_create(buf_pool_get_max_size() / (DICT_POOL_PER_TABLE_HASH * UNIV_WORD_SIZE)); dict_sys->col_hash = hash_create(buf_pool_get_max_size() / (DICT_POOL_PER_COL_HASH * UNIV_WORD_SIZE)); dict_sys->size = 0; UT_LIST_INIT(dict_sys->table_LRU); rw_lock_create(&dict_operation_lock); rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION); dict_foreign_err_file = os_file_create_tmpfile(); ut_a(dict_foreign_err_file); mutex_create(&dict_foreign_err_mutex); mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH);}/**************************************************************************Returns a table object and memoryfixes it. NOTE! This is a high-levelfunction to be used mainly from outside the 'dict' directory. Inside thisdirectory dict_table_get_low is usually the appropriate function. */dict_table_t*dict_table_get(/*===========*/ /* out: table, NULL if does not exist */ const char* table_name, /* in: table name */ trx_t* trx) /* in: transaction handle or NULL */{ dict_table_t* table; UT_NOT_USED(trx); mutex_enter(&(dict_sys->mutex)); table = dict_table_get_low(table_name); mutex_exit(&(dict_sys->mutex)); if (table != NULL) { if (!table->stat_initialized) { dict_update_statistics(table); } } return(table);}/**************************************************************************Returns a table object and increments MySQL open handle count on the table. */dict_table_t*dict_table_get_and_increment_handle_count(/*======================================*/ /* out: table, NULL if does not exist */ const char* table_name, /* in: table name */ trx_t* trx) /* in: transaction handle or NULL */{ dict_table_t* table; UT_NOT_USED(trx); mutex_enter(&(dict_sys->mutex)); table = dict_table_get_low(table_name); if (table != NULL) { table->n_mysql_handles_opened++; } mutex_exit(&(dict_sys->mutex)); if (table != NULL) { if (!table->stat_initialized && !table->ibd_file_missing) { dict_update_statistics(table); } } return(table);}/**************************************************************************Adds a table object to the dictionary cache. */voiddict_table_add_to_cache(/*====================*/ dict_table_t* table) /* in: table */{ ulint fold; ulint id_fold; ulint i; ut_ad(table);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_ad(table->n_def == table->n_cols - DATA_N_SYS_COLS); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); ut_ad(table->cached == FALSE); fold = ut_fold_string(table->name); id_fold = ut_fold_dulint(table->id); table->cached = TRUE; /* NOTE: the system columns MUST be added in the following order (so that they can be indexed by the numerical value of DATA_ROW_ID, etc.) and as the last columns of the table memory object. The clustered index will not always physically contain all system columns. */ dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS, DATA_ROW_ID | DATA_NOT_NULL, DATA_ROW_ID_LEN, 0);#if DATA_ROW_ID != 0#error "DATA_ROW_ID != 0"#endif dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS, DATA_TRX_ID | DATA_NOT_NULL, DATA_TRX_ID_LEN, 0);#if DATA_TRX_ID != 1#error "DATA_TRX_ID != 1"#endif dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS, DATA_ROLL_PTR | DATA_NOT_NULL, DATA_ROLL_PTR_LEN, 0);#if DATA_ROLL_PTR != 2#error "DATA_ROLL_PTR != 2"#endif dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS, DATA_MIX_ID | DATA_NOT_NULL, DATA_MIX_ID_LEN, 0);#if DATA_MIX_ID != 3#error "DATA_MIX_ID != 3"#endif /* This check reminds that if a new system column is added to the program, it should be dealt with here */ #if DATA_N_SYS_COLS != 4#error "DATA_N_SYS_COLS != 4"#endif /* Look for a table with the same name: error if such exists */ { dict_table_t* table2; HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2, (ut_strcmp(table2->name, table->name) == 0)); ut_a(table2 == NULL); } /* Look for a table with the same id: error if such exists */ { dict_table_t* table2; HASH_SEARCH(id_hash, dict_sys->table_id_hash, id_fold, table2, (ut_dulint_cmp(table2->id, table->id) == 0)); ut_a(table2 == NULL); } if (table->type == DICT_TABLE_CLUSTER_MEMBER) { table->mix_id_len = mach_dulint_get_compressed_size( table->mix_id); mach_dulint_write_compressed(table->mix_id_buf, table->mix_id); } /* Add the columns to the column hash table */ for (i = 0; i < table->n_cols; i++) { dict_col_add_to_cache(table, dict_table_get_nth_col(table, i)); } /* Add table to hash table of tables */ HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); /* Add table to hash table of tables based on table id */ HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold, table); /* Add table to LRU list of tables */ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); /* If the dictionary cache grows too big, trim the table LRU list */ dict_sys->size += mem_heap_get_size(table->heap); /* dict_table_LRU_trim(); */}/**************************************************************************Looks for an index with the given id. NOTE that we do not reservethe dictionary mutex: this function is for emergency purposes likeprinting info of a corrupt database page! */dict_index_t*dict_index_find_on_id_low(/*======================*/ /* out: index or NULL if not found from cache */ dulint id) /* in: index id */{ dict_table_t* table; dict_index_t* index; table = UT_LIST_GET_FIRST(dict_sys->table_LRU); while (table) { index = dict_table_get_first_index(table); while (index) { if (0 == ut_dulint_cmp(id, index->tree->id)) { /* Found */ return(index); } index = dict_table_get_next_index(index); } table = UT_LIST_GET_NEXT(table_LRU, table); } return(NULL);}/**************************************************************************Renames a table object. */ibooldict_table_rename_in_cache(/*=======================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table */ const char* new_name, /* in: new name */ ibool rename_also_foreigns)/* in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */{ dict_foreign_t* foreign; dict_index_t* index; ulint fold; ulint old_size; char* old_name; ibool success; ulint i; ut_ad(table);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ old_size = mem_heap_get_size(table->heap); fold = ut_fold_string(new_name); /* Look for a table with the same name: error if such exists */ { dict_table_t* table2; HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2, (ut_strcmp(table2->name, new_name) == 0)); if (table2) { fprintf(stderr,"InnoDB: Error: dictionary cache already contains a table of name %s\n", new_name); return(FALSE); } } /* If the table is stored in a single-table tablespace, rename the .ibd file */ if (table->space != 0) { if (table->dir_path_of_temp_table != NULL) { fprintf(stderr,"InnoDB: Error: trying to rename a table %s (%s) created with CREATE\n""InnoDB: TEMPORARY TABLE\n", table->name, table->dir_path_of_temp_table); success = FALSE; } else { success = fil_rename_tablespace(table->name, table->space, new_name); } if (!success) { return(FALSE); } } /* Reposition the columns in the column hash table; they are hashed according to the pair (table name, column name) */ for (i = 0; i < table->n_cols; i++) { dict_col_reposition_in_cache(table, dict_table_get_nth_col(table, i), new_name); } /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -