📄 dict0crea.c
字号:
the built tuple is allocated */{ dtuple_t* search_tuple; dfield_t* field1; dfield_t* field2; ut_ad(tuple && heap); search_tuple = dtuple_create(heap, 2); field1 = dtuple_get_nth_field(tuple, 0); field2 = dtuple_get_nth_field(search_tuple, 0); dfield_copy(field2, field1); field1 = dtuple_get_nth_field(tuple, 1); field2 = dtuple_get_nth_field(search_tuple, 1); dfield_copy(field2, field1); ut_ad(dtuple_validate(search_tuple)); return(search_tuple);}/*******************************************************************Builds an index definition row to insert. */staticulintdict_build_index_def_step(/*======================*/ /* out: DB_SUCCESS or error code */ que_thr_t* thr, /* in: query thread */ ind_node_t* node) /* in: index create node */{ dict_table_t* table; dict_index_t* index; dtuple_t* row; trx_t* trx;#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); index = node->index; table = dict_table_get_low(index->table_name); if (table == NULL) { return(DB_TABLE_NOT_FOUND); } trx->table_id = table->id; node->table = table; ut_ad((UT_LIST_GET_LEN(table->indexes) > 0) || (index->type & DICT_CLUSTERED)); index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID); /* Inherit the space id from the table; we store all indexes of a table in the same tablespace */ index->space = table->space; node->page_no = FIL_NULL; row = dict_create_sys_indexes_tuple(index, node->heap); node->ind_row = row; ins_node_set_new_row(node->ind_def, row); return(DB_SUCCESS);}/*******************************************************************Builds a field definition row to insert. */staticulintdict_build_field_def_step(/*======================*/ /* out: DB_SUCCESS */ ind_node_t* node) /* in: index create node */{ dict_index_t* index; dtuple_t* row; index = node->index; row = dict_create_sys_fields_tuple(index, node->field_no, node->heap); ins_node_set_new_row(node->field_def, row); return(DB_SUCCESS);}/*******************************************************************Creates an index tree for the index if it is not a member of a cluster. */staticulintdict_create_index_tree_step(/*========================*/ /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ ind_node_t* node) /* in: index create node */{ dict_index_t* index; dict_table_t* sys_indexes; dict_table_t* table; dtuple_t* search_tuple; btr_pcur_t pcur; mtr_t mtr;#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ index = node->index; table = node->table; sys_indexes = dict_sys->sys_indexes; if (index->type & DICT_CLUSTERED && table->type == DICT_TABLE_CLUSTER_MEMBER) { /* Do not create a new index tree: entries are put to the cluster tree */ return(DB_SUCCESS); } /* Run a mini-transaction in which the index tree is allocated for the index and its root address is written to the index entry in sys_indexes */ mtr_start(&mtr); search_tuple = dict_create_search_tuple(node->ind_row, node->heap); btr_pcur_open(UT_LIST_GET_FIRST(sys_indexes->indexes), search_tuple, PAGE_CUR_L, BTR_MODIFY_LEAF, &pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr); node->page_no = btr_create(index->type, index->space, index->id, table->comp, &mtr); /* printf("Created a new index tree in space %lu root page %lu\n", index->space, index->page_no); */ page_rec_write_index_page_no(btr_pcur_get_rec(&pcur), DICT_SYS_INDEXES_PAGE_NO_FIELD, node->page_no, &mtr); btr_pcur_close(&pcur); mtr_commit(&mtr); if (node->page_no == FIL_NULL) { return(DB_OUT_OF_FILE_SPACE); } return(DB_SUCCESS);}/***********************************************************************Drops the index tree associated with a row in SYS_INDEXES table. */voiddict_drop_index_tree(/*=================*/ rec_t* rec, /* in: record in the clustered index of SYS_INDEXES table */ mtr_t* mtr) /* in: mtr having the latch on the record page */{ ulint root_page_no; ulint space; byte* ptr; ulint len; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_a(!dict_sys->sys_indexes->comp); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ut_ad(len == 4); root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); if (root_page_no == FIL_NULL) { /* The tree has already been freed */ return; } ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_SPACE_NO_FIELD, &len); ut_ad(len == 4); space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); if (!fil_tablespace_exists_in_mem(space)) { /* It is a single table tablespace and the .ibd file is missing: do nothing */ return; } /* We free all the pages but the root page first; this operation may span several mini-transactions */ btr_free_but_not_root(space, root_page_no); /* Then we free the root page in the same mini-transaction where we write FIL_NULL to the appropriate field in the SYS_INDEXES record: this mini-transaction marks the B-tree totally freed */ /* printf("Dropping index tree in space %lu root page %lu\n", space, root_page_no); */ btr_free_root(space, root_page_no, mtr); page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, FIL_NULL, mtr);}/***********************************************************************Truncates the index tree associated with a row in SYS_INDEXES table. */ulintdict_truncate_index_tree(/*=====================*/ /* out: new root page number, or FIL_NULL on failure */ dict_table_t* table, /* in: the table the index belongs to */ rec_t* rec, /* in: record in the clustered index of SYS_INDEXES table */ mtr_t* mtr) /* in: mtr having the latch on the record page. The mtr may be committed and restarted in this call. */{ ulint root_page_no; ulint space; ulint type; dulint index_id; byte* ptr; ulint len; ulint comp; dict_index_t* index;#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ ut_a(!dict_sys->sys_indexes->comp); ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, &len); ut_ad(len == 4); root_page_no = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); if (root_page_no == FIL_NULL) { /* The tree has been freed. */ ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Trying to TRUNCATE" " a missing index of table %s!\n", table->name); return(FIL_NULL); } ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_SPACE_NO_FIELD, &len); ut_ad(len == 4); space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr); if (!fil_tablespace_exists_in_mem(space)) { /* It is a single table tablespace and the .ibd file is missing: do nothing */ ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Trying to TRUNCATE" " a missing .ibd file of table %s!\n", table->name); return(FIL_NULL); } ptr = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_TYPE_FIELD, &len); ut_ad(len == 4); type = mach_read_from_4(ptr); ptr = rec_get_nth_field_old(rec, 1, &len); ut_ad(len == 8); index_id = mach_read_from_8(ptr); /* We free all the pages but the root page first; this operation may span several mini-transactions */ btr_free_but_not_root(space, root_page_no); /* Then we free the root page in the same mini-transaction where we create the b-tree and write its new root page number to the appropriate field in the SYS_INDEXES record: this mini-transaction marks the B-tree totally truncated */ comp = page_is_comp(btr_page_get( space, root_page_no, RW_X_LATCH, mtr)); btr_free_root(space, root_page_no, mtr); /* We will temporarily write FIL_NULL to the PAGE_NO field in SYS_INDEXES, so that the database will not get into an inconsistent state in case it crashes between the mtr_commit() below and the following mtr_commit() call. */ page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD, FIL_NULL, mtr); /* We will need to commit the mini-transaction in order to avoid deadlocks in the btr_create() call, because otherwise we would be freeing and allocating pages in the same mini-transaction. */ mtr_commit(mtr); /* mtr_commit() will invalidate rec. */ rec = NULL; mtr_start(mtr); /* Find the index corresponding to this SYS_INDEXES record. */ for (index = UT_LIST_GET_FIRST(table->indexes); index; index = UT_LIST_GET_NEXT(indexes, index)) { if (!ut_dulint_cmp(index->id, index_id)) { break; } } root_page_no = btr_create(type, space, index_id, comp, mtr); if (index) { index->tree->page = root_page_no; } else { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Index %lu %lu of table %s is missing\n" "InnoDB: from the data dictionary during TRUNCATE!\n", ut_dulint_get_high(index_id), ut_dulint_get_low(index_id), table->name); } return(root_page_no);}/*************************************************************************Creates a table create graph. */tab_node_t*tab_create_graph_create(/*====================*/ /* out, own: table create node */ dict_table_t* table, /* in: table to create, built as a memory data structure */ mem_heap_t* heap) /* in: heap where created */{ tab_node_t* node; node = mem_heap_alloc(heap, sizeof(tab_node_t)); node->common.type = QUE_NODE_CREATE_TABLE; node->table = table; node->state = TABLE_BUILD_TABLE_DEF; node->heap = mem_heap_create(256); node->tab_def = ins_node_create(INS_DIRECT, dict_sys->sys_tables, heap); node->tab_def->common.parent = node; node->col_def = ins_node_create(INS_DIRECT, dict_sys->sys_columns, heap); node->col_def->common.parent = node; node->commit_node = commit_node_create(heap); node->commit_node->common.parent = node; return(node);}/*************************************************************************Creates an index create graph. */ind_node_t*ind_create_graph_create(/*====================*/ /* out, own: index create node */ dict_index_t* index, /* in: index to create, built as a memory data structure */ mem_heap_t* heap) /* in: heap where created */{ ind_node_t* node; node = mem_heap_alloc(heap, sizeof(ind_node_t)); node->common.type = QUE_NODE_CREATE_INDEX; node->index = index; node->state = INDEX_BUILD_INDEX_DEF; node->page_no = FIL_NULL; node->heap = mem_heap_create(256); node->ind_def = ins_node_create(INS_DIRECT, dict_sys->sys_indexes, heap); node->ind_def->common.parent = node; node->field_def = ins_node_create(INS_DIRECT, dict_sys->sys_fields, heap); node->field_def->common.parent = node; node->commit_node = commit_node_create(heap); node->commit_node->common.parent = node; return(node);}/***************************************************************Creates a table. This is a high-level function used in SQL execution graphs. */que_thr_t*dict_create_table_step(/*===================*/ /* out: query thread to run next or NULL */ que_thr_t* thr) /* in: query thread */{ tab_node_t* node; ulint err = DB_ERROR; trx_t* trx; ut_ad(thr);#ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ trx = thr_get_trx(thr); node = thr->run_node; ut_ad(que_node_get_type(node) == QUE_NODE_CREATE_TABLE); if (thr->prev_node == que_node_get_parent(node)) { node->state = TABLE_BUILD_TABLE_DEF; } if (node->state == TABLE_BUILD_TABLE_DEF) { /* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ err = dict_build_table_def_step(thr, node); if (err != DB_SUCCESS) { goto function_exit; } node->state = TABLE_BUILD_COL_DEF; node->col_no = 0; thr->run_node = node->tab_def; return(thr); } if (node->state == TABLE_BUILD_COL_DEF) { if (node->col_no < (node->table)->n_def) { err = dict_build_col_def_step(node); if (err != DB_SUCCESS) { goto function_exit; } node->col_no++; thr->run_node = node->col_def; return(thr); } else { node->state = TABLE_COMMIT_WORK; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -