Post

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 执行触发器