[MySQL源码] 一条简单insert语句的调用栈

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

以下仅用于本人调试MySQL所用,不具备可读性。

———————————————————–

CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;

insert into t1 values (4,2);

ha_innobase::write_row

 |–>row_insert_for_mysql 

     |–>转换记录格式row_mysql_convert_row_to_innobase

     |–>保存检查点savept = trx_savept_take(trx);

     |–>row_ins_step

        |–>加IX锁lock_table(0, node->table, LOCK_IX, thr)

        |–> row_ins     //轮询索引,向表中插入记录,这里只有聚集索引

        .   |–>row_ins_index_entry_step

        .      |–>构建索引记录(node->entry)row_ins_index_entry_set_vals

        .      |–>row_ins_index_entry(node->index, node->entry, 0, TRUE, thr)

        .      .   |–>检查外键约束row_ins_check_foreign_constraints

        .      .   |->使用如下两步尝试插入记录

                   >>step1.row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,n_ext, thr)/* Try first optimistic descent to the B-tree */

                   >>step2,若step1失败,row_ins_index_entry_low(BTR_MODIFY_TREE, index, entry,n_ext, thr);/* Try then pessimistic descent to the B-tree */

                       |–> row_ins_index_entry_low

                             |–>确定search_mode

                             1)如果是聚集索引,search_mode为传参BTR_MODIFY_LEAF或BTR_MODIFY_TREE

                             2)当前事务的check_unique_secondary为false时(由变量unique_checks控制,默认为true,表示检查唯一索引约束),search_mode = mode | BTR_INSERT | BTR_IGNORE_SEC_UNIQUE

                             3)否则,search_mode = mode | BTR_INSERT

                             |–>btr_cur_search_to_nth_level  查询索引树,将cursor移动到记录相应的位置(待分析)

                             |–>检测是否有dup key,主键索引调用row_ins_duplicate_error_in_clust,二级索引调用row_ins_scan_sec_index_for_duplicate

                             |–>modify = row_ins_must_modify  (待分析)

                             >>当modify!=0时,表明已经有一个足够长的common prefix,直接覆盖插入记录(待分析)

                             >>当modify=0时:

                               1)当mode=BTR_MODIFY_LEAF时,调用btr_cur_optimistic_insert,尝试向一个索引page中插入记录,如果页面空闲空间太小,则返回失败

                                   |–>btr_cur_ins_lock_and_undo //检查是否有锁冲突,并插入undolog

                                         |–>lock_rec_insert_check_and_lock //检查锁冲突

                                               |–>没有下一个记录的锁冲突,即lock_rec_get_first返回NULL,更新二级索引trx id,返回

                                               |–>调用lock_rec_other_has_conflicting,检查是否有其他事务锁有下一个记录的LOCK_X, LOCK_GAP和LOCK_INSERT_INTENTION锁

                                               |–>检测到有冲突lock_rec_enqueue_waiting

                                                       |–> 创建锁记录lock_rec_create,type_code为LOCK_X | LOCK_GAP|LOCK_INSERT_INTENTION

                                                       |–>检测死锁

                                         |–>如果是聚集索引且不是Insert buffer

                                               |–>写入undo信息 trx_undo_report_row_operation(待分析)

                                               |–>设置聚集索引记录的trx id和回滚段指针,row_upd_index_entry_sys_field

                                    |–>插入记录page_cur_tuple_insert

                                    |–>更新该page的哈希索引btr_search_update_hash_on_insert(待分析)

                                    |–>继承下一条记录的gap锁?(inherit为TRUE),调lock_update_insert,这里不调用 (待分析) 

                                 2)否则

                                    a)调用buf_LRU_buf_pool_running_out,返回true,表示少于25%的buffer pool可用。根据注释,对于大事务,会将锁存储在buffer pool中(待证实)

                                    b)调用btr_cur_pessimistic_insert(待分析)

           

drop table t1;

CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;

insert into t1 values (1,2);

insert into t1 values (1,5) on duplicate key update b = b+1;

————————————————-

函数调用逻辑:

write_record->handler::ha_write_row->ha_innobase::write_row->

row_insert_for_mysql

     —->row_ins_step->row_ins->row_ins_index_entry

          |–>row_ins_index_entry_low

             |–>调用row_ins_duplicate_error_in_clust检测是否有dup key错误。

                   |–>对记录加锁

                      >>对于REPLACE, LOAD DATAFILE REPLACE以及INSERT ON DUPLICATE KEY UPDATE操作,对记录加一个排他锁(LOCK_X)row_ins_set_exclusive_rec_lock

                            a)聚集索引lock_clust_rec_read_check_and_lock

                            b)二级索引lock_sec_rec_read_check_and_lock

                      >>否则,加一个共享锁(LOCK_S)row_ins_set_shared_rec_lock

                   |–>调用row_ins_dupl_error_with_rec检查物理记录和将要插入的记录是否相同


从Innodb层返回到Server层后,write_record函数根据返回的错误值,继续下面的逻辑

|–>判断是否是dup key错误

|–>if (table->file->extra(HA_EXTRA_FLUSH_CACHE))    //  bug#52020相关点,稍后再议

|–>一堆乱七八糟的检查,构建记录等….

|–>row_update_for_mysql传递record到innodb更新数据

     |–>row_upd_step->row_upd

       |–>row_upd_clust_step

          |–>如果没有x锁,则尝试加锁lock_clust_rec_modify_check_and_lock

          |–>row_upd_clust_rec(待分析)

                   |–>btr_cur_optimistic_update


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
监控 数据可视化 关系型数据库
微服务架构+Java+Spring Cloud +UniApp +MySql智慧工地系统源码
项目管理:项目名称、施工单位名称、项目地址、项目地址、总造价、总面积、施工准可证、开工日期、计划竣工日期、项目状态等。
305 6
|
3月前
|
JavaScript 关系型数据库 MySQL
基于JavaWeb和mysql实现校园订餐前后台管理系统(源码+数据库)
基于JavaWeb和mysql实现校园订餐前后台管理系统(源码+数据库)
|
3月前
|
NoSQL 关系型数据库 MySQL
基于Python和mysql开发的智慧校园答题考试系统(源码+数据库+程序配置说明书+程序使用说明书)
基于Python和mysql开发的智慧校园答题考试系统(源码+数据库+程序配置说明书+程序使用说明书)
|
2月前
|
SQL 关系型数据库 MySQL
MySQL技能完整学习列表3、SQL语言基础——1、SQL(Structured Query Language)简介——2、基本SQL语句:SELECT、INSERT、UPDATE、DELETE
MySQL技能完整学习列表3、SQL语言基础——1、SQL(Structured Query Language)简介——2、基本SQL语句:SELECT、INSERT、UPDATE、DELETE
49 0
|
3月前
|
NoSQL 关系型数据库 MySQL
基于Python和mysql开发的BBS问答社区管理系统(源码+数据库+程序配置说明书+程序使用说明书)
基于Python和mysql开发的BBS问答社区管理系统(源码+数据库+程序配置说明书+程序使用说明书)
|
3月前
|
SQL 存储 缓存
SQL语句在MySQL中是如何执行的
SQL语句在MySQL中是如何执行的
45 0
|
3月前
|
前端开发 IDE Java
基于Springboot+MYSQL+Maven实现的宠物医院管理系统(源码+数据库+运行指导文档+项目运行指导视频)
基于Springboot+MYSQL+Maven实现的宠物医院管理系统(源码+数据库+运行指导文档+项目运行指导视频)
163 0
|
2天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
10天前
|
监控 数据可视化 安全
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
环境实时数据、动态监测报警,实时监控施工环境状态,有针对性地预防施工过程中的环境污染问题,打造文明生态施工,创造绿色的生态环境。
8 0
智慧工地SaaS可视化平台源码,PC端+APP端,支持二开,项目使用,微服务+Java++vue+mysql
|
10天前
|
监控 安全 关系型数据库
基于vue2 + element +mysql医院不良事件上报系统源码
不良事件管理系统从时间上报、PDCA分析、事件整改、评估效果实行闭环管理和分析,满足医院追根溯源,全流程闭环管理,提高不良事件上报率,减少同类不良事件发生,提高医疗安全。通过报告不良事件,及时发现潜在的不安全因素
18 1