其中:
- 调用 row_mysql_store_col_in_innobase_format 函数将列值保存在 dtuple_t::dfield_t 中 。
const byte* ptr = mysql_data; const dtype_t* dtype; ulinttype; dtype = dfield_get_type(dfield); type = dtype->mtype;// 计算 col_len...dfield_set_data(dfield, ptr, col_len);其中:- 获取 dtype、计算 col_len
- 调用 dfield_set_data 函数保存数据完成行记录格式的转换
/* Sets pointer to the data and length in a field. */UNIV_INLINEvoiddfield_set_data(/*============*/ dfield_t* field, /*!< in: field */ const void* data, /*!< in: data */ ulintlen) /*!< in: length or UNIV_SQL_NULL */{ field->data = https://www.isolves.com/it/sjk/MYSQL/2023-12-28/(void*) data; field->ext = 0; field->len = static_cast(len);} 其中:- 向 dfield_t 结构体中保存字段数据、字段长度
dtuple_t* row -> dtuple_t* entryrow_ins_step 函数中创建 ins_node_t 并调用 row_ins 函数 。
// 创建 ins_node_t node = static_cast<ins_node_t*>(thr->run_node);// 给表加上意向锁err = lock_table(0, node->table, LOCK_IX, thr);/* DO THE CHECKS OF THE CONSISTENCY CONSTRAINTS HERE */ // 调用 row_ins() 插入记录到主键索引、二级索引 err = row_ins(node, thr);row_ins 函数中遍历表的每个 index,插入 index entry 。// 遍历所有索引,向每个索引中插入记录 while (node->index != NULL) {/* 向索引中插入记录 */err = row_ins_index_entry_step(node, thr);// 插入记录到主键索引或二级索引成功后获取下一个索引// node->index、entry 指向表中的下一个索引node->index = dict_table_get_next_index(node->index);node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry);其中:- 循环调用 row_ins_index_entry_step 函数插入记录,其中入参 node 就是 row_mysql_convert_row_to_innobase 函数转换后的 row_prebuilt_t->ins_node_t;
- 每次插入索引时更新 ins_node_t->index 与 ins_node_t->entry , 因此行数据对应的所有索引复用同一个 ins_node_t 变量,其中 ins_node_t->row 保持不变 。
row_ins_index_entry_step 函数中向指定索引中插入记录 。
// storage/innobase/row/row0insert.cc/* Inserts a single index entry to the table. */static MY_ATTRIBUTE((nonnull, warn_unused_result))dberr_trow_ins_index_entry_step(/*=====================*/ ins_node_t* node, /*!< in: row insert node */ que_thr_t* thr) /*!< in: query thread */{/*给索引项赋值*/ err = row_ins_index_entry_set_vals(node->index, node->entry, node->row); /*插入索引项*/ err = row_ins_index_entry(node->index, node->entry, thr);}其中:- 调用 row_ins_index_entry_set_vals 函数遍历索引的每个字段并赋值,其中将 innobase format field 的值赋给对应的 index entry field 。
/** Sets the values of the dtuple fields in entry from the values of appropriate columns in row. */dberr_trow_ins_index_entry_set_vals( const dict_index_t* index, dtuple_t*entry, const dtuple_t*row){ n_fields = dtuple_get_n_fields(entry); for (i = 0; i < n_fields + num_v; i++) {dfield_t* field;const dfield_t* row_field;ulintlen;// 获取 fieldfield = dtuple_get_nth_field(entry, i);row_field = dtuple_get_nth_field(row, ind_field->col->ind);len = dfield_get_len(row_field);// 写入 fielddfield_set_data(field, dfield_get_data(row_field), len);}其中:- 与 row 相同 , 循环调用 dfield_set_data 方法给索引 entry 中的每个字段 field 赋值 。
cursorrow_ins_index_entry 函数中以插入主键索引为例 。
row_ins_clust_index_entry_low 函数中以乐观插入为例 。
// storage/innbase/row/row0ins.ccdberr_trow_ins_clust_index_entry_low(/*==========================*/ ulintflags, /*!< in: undo logging and locking flags */ ulintmode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,depending on whether we wish optimistic orpessimistic descent down the index tree */ dict_index_t* index, /*!< in: clustered index */ ulintn_uniq, /*!< in: 0 or index->n_uniq */ dtuple_t* entry, /*!< in/out: index entry to insert */ ulintn_ext, /*!< in: number of externally stored columns */ que_thr_t* thr, /*!< in: query thread */ booldup_chk_only)/*!< in: if true, just do duplicate checkand return. don't execute actual insert. */{btr_pcur_t pcur;btr_cur_t* cursor;// offsetsulintoffsets_[REC_OFFS_NORMAL_SIZE]; ulint*offsets= offsets_;/* Note that we use PAGE_CUR_LE as the search mode, because then the function will return in both low_match and up_match of the cursor sensible values */ // 插入操作的 search_mode 默认是 PAGE_CUR_LE,即插在最后一个小于等于该 dtuple 的 rec_t 后 // btr_pcur_open 函数内部调用 btr_cur_search_to_nth_level 函数 btr_pcur_open(index, entry, PAGE_CUR_LE, mode, &pcur, &mtr);// 从 btr_pcur_t 中获取 btr_cur_t(tree cursor) cursor = btr_pcur_get_btr_cur(&pcur); cursor->thr = thr;rec_t* insert_rec;/* 乐观插入 */err = btr_cur_optimistic_insert(flags, cursor, &offsets, &offsets_heap,entry, &insert_rec, &big_rec,n_ext, thr, &mtr);}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MySQL:级联从库延迟数据库的延迟计算问题
- 提醒!微信、支付宝这个功能,建议关闭
- 支付宝2023年度报告发布,多巴胺经济、小攒青年、万事打卡成关键词
- 怎么减双下巴 怎么减双下巴最快最有效
- 驻点是什么意思 驻店是什么意思
- 电热水器安装方法及维修技巧
- 安顺十佳特色美食,安顺美食排名前十名
- 竹子是? 竹子实际是什么
- 整容脸、演戏烂,关系户三个字直接写在剧版《三大队》女六号脸上
- 裤腿大了怎么办 裤腿很大怎么办
