MySQL聚集索引插入
聚集索引插入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
> mysql_execute_command SQLCOM_INSERT
> open_temporary_tables 打开临时表
> insert_precheck 检查对第一个表有修改权限、对其他表有查询权限
> mysql_insert mysql层执行插入
> upgrade_lock_type 如果请求的锁与当前连接模式或表操作不兼容,升级锁(针对thr_lock)
> open_normal_and_derived_tables 打开表
> mysql_prepare_insert 准备插入
> mysql_prepare_insert_check_table 检查表是否可以被修改,第一个表是需要被插入的,需要INSERT_ACL权限,其他表需要SELECT_ACL权限
> setup_fields 检查、构造待插入的值
> fill_recode 将字段结构中的值填充到缓冲区
> write_record 将记录写到表中,唤醒触发器
> ha_write_row
> innobase::write_row 进入innodb层
> row_insert_for_mysql
> row_mysql_convert_row_to_innobase 将mysql格式的行转换成innobase格式
> trx_savept_take 获取事务当前的保存点,savept.least_undo_no = trx.undo_no
> row_ins_step
> lock_table 对表上IX锁
> if INS_SEARCHED: thr_run_node = sel_node, reutrn thr
> row_ins
> row_ins_alloc_row_id_step 分配rowid
> row_ins_index_entry_step 对表上所有索引执行
> row_ins_index_entry_set_vals 设置索引需要的字段
> row_ins_index_entry 插入索引记录到索引中,先乐观后悲观
>若聚集索引 row_ins_clust_index_entry
> row_ins_check_foreign_constraints 检查外键约束
>MODIFY_LEAF方式 row_ins_clust_index_entry_low
> mtr_start 开启mtr
> btr_cur_search_to_nth_level PAGE_CUR_LE方式搜素b树游标到叶子层
>IF row_ins_must_modify_rec 插入操作变成修改已存在的记录
> row_ins_clust_index_entry_by_modify 插入操作变成重置删除标记、更新已存在但被删除的记录
>IF big_rec
> btr_store_big_rec_extern_fields 存储大对象,将指针存进记录中
>IF 索引是在线DDL
> row_log_table_insert 记录插入的row_log
> mtr_commit 提交mtr
>ELSE
>IF not MODIFY_TREE btr_cur_optimistic_insert 乐观插入B树
>ELSE 先乐观,若失败则悲观
>IF 索引是在线DDL
> row_log_table_insert 记录插入的row_log
> mtr_commit 提交mtr
>若失败,MODIFY_TREE方式row_ins_clust_index_entry_low
>若二级索引 row_ins_sec_index_entry
> row_update_statistics_if_needed 更新表的统计信息
> binlog_log_row 记录binlog
> process_triggers 执行触发器