mysql insert 源码_MySQL源码学习(四):从insert看btr

2023-10-19 17:30

本文主要是介绍mysql insert 源码_MySQL源码学习(四):从insert看btr,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Btr: B+ Tree,是innodb的核心数据结构,它作为数据的索引,让数据库能够快速找到指定的数据。

B+ Tree的相关说明网上已经很多,本文通过insert操作的调用栈,来分析btr的操作过程。

·Btr操作在insert的哪个过程中被调用?

ac0925e43487cd09b2613c5282f5cd5a.png

图1 insert的函数调用栈(btr部分)

图1是一次insert操作打印的trace日志。大家可以看到第一行write_record函数,这个步骤是在mysql_insert函数中调用的。下面先调用innobase的write_row接口来执行pimary key的auto_increment操作,生成主键。然后再调用row_ins方法来向btr中插入数据。

本文要关注的流程主要在row_ins中的流程。

·row_ins

该函数在storage/innobase/row/row0ins.cc文件中,可以看出这是跟存储引擎相关的操作。

af5eb5f5d9e2c6a1bc5c0dfdfb26547a.png

图2 row_ins的主要流程

其中,Trace日志中打印了其中的3个流程,就包含在“插入index和数据”这个步骤中”:

row_ins_index_entry_step

|  row_ins_cluster_index_entry_low

|  |  btr_cur_search_to_nth_level

row_ins_index_entry_step:向表中插入一个索引

row_ins_cluster_index_entry_low: cluster_index这里是指聚簇索引,很熟悉的词吧。这里会插入一个聚簇索引,并且忽略外键的限制。如果发现主键已经存在(主键冲突),那么除非这条已经有的记录已经被事务标记为“已删除”,否则就会报主键冲突错误。

btr_cur_search_to_nth_level:  在btr上搜索指定的索引,并把cursor定位到指定的level。改函数支持两种模式,PAGE_CUR_LE和PAGE_CUR_GE。Insert使用PAGE_CUR_LE这种方式进行搜索。

·分配index

84a794f21f039b5b808013e00a9b5f70.png

图3 index的获取

row_ins函数第一部分,通过dict_table_get_first_index(node->table)来获取索引。Row_ins_get_row_from_select和row_ins_get_row_from_values分别对应了INSERT … SELECT语句和INSERT … values语句(包括多个values)。这两个函数中会把value值保存到node对象中。

·插入数据

1e4377e48aa758d6ea7d9bf415732537.png

图4 index和数据的插入

如图4所示,row_ins_index_entry_step方法是执行index插入的入口方法。返回如果成功,则说明插入成功。如果返回错误码是DB_DUPLICTE_KEY,则会判断是否包含了on duplicate update的语法,如果有的话,则会将索引保存到node->duplicate对象中,以便后面继续执行。如果没有包含on duplicate update的语法,则直接返回主键冲突的错误。

row_ins_index_entry_step中的三个主要流程上面已经介绍过。这里重点看row_ins_clust_index_entry_low函数中的流程:

bea701543bfbf7ea9ef4da8cd442c4ef.png

图5 获取btr中的cursor

btr_pcur_open方法,获取到这个新生成的index到底放到btr的哪个位置。这个位置,就由Cursor来标记标记。

bf7ee4f6496cd379650786741ef1985e.png

图6 btr_pcur_get_btr_cur宏定义

·pcur和cursor的关系

pcur是persistent cursor。因为btr是会分裂和变动的,当btr被分裂时,cursor的位置也会对应的进行变化。因此通过一层pcur的封装,将cursor的变化对外屏蔽,针对一个index,我们只需要通过一个固定的pcur去获取当前的cursor就可以了。

678eebed8355fbada23da252aa2eb892.png

图7 btr_pcur_t依赖于btr_cur

获取到了真实的cursor后,就可以拿到对应的leaf节点,就是具体的page。如图8所示,btr的leaf是page,而不是record,从这两个代码就可以证明。而插入的数据最终,是写入到rec_t中的。这里只是对page是否有记录做了初步的判断,记录的插入请看图9:。

2e6e930478cc52dc3a0b1a2f2e82f2c5.png

图8 通过cursor拿到page

请看图9中的btr_cur_optimistic_insert方法:

a2ce1b0622536d31fedd1e7e0f2023bc.png

图9 数据的插入

该方法会把记录写入到record中,同时如果需要重做btr,会着这里面进行调整。

0b39f9dc30f8b1634c88a4aecdc94f25.png

图10 插入流程

如图10所示,首先通过cursor拿到page,并记录下插入之间的record地址。通过page_cur_tuple_direct_insert方法插入记录后。再次通过相同cursor拿到record地址,并判断插入前和插入后的record地址是否相同。如果不同,说明btr发生了重构。这也证明了corsor指向的btr位置是在不断变化的。Corsor是在btr上的绝对位置,而这个位置上的数据会因为btr的重构而改变,因此外面加入了一层psersistent cursor,使得能够通过同一个index快速找到cursor。

这篇关于mysql insert 源码_MySQL源码学习(四):从insert看btr的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/241279

相关文章

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.

基于SpringBoot+Mybatis实现Mysql分表

《基于SpringBoot+Mybatis实现Mysql分表》这篇文章主要为大家详细介绍了基于SpringBoot+Mybatis实现Mysql分表的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录基本思路定义注解创建ThreadLocal创建拦截器业务处理基本思路1.根据创建时间字段按年进

Python3.6连接MySQL的详细步骤

《Python3.6连接MySQL的详细步骤》在现代Web开发和数据处理中,Python与数据库的交互是必不可少的一部分,MySQL作为最流行的开源关系型数据库管理系统之一,与Python的结合可以实... 目录环境准备安装python 3.6安装mysql安装pymysql库连接到MySQL建立连接执行S

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分