MySQL:一个简单insert语句的大概流程

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介:

简单记录,可能有误,主要记录重要的接口以备后用。


一、操作说明

我建了一个简单的表,插入一个简单的数据。

mysql> create table testin(id int);
Query OK, 0 rows affected (2.38 sec)
mysql> insert into testin values(10);
Query OK, 1 row affected (0.02 sec)

主要跟踪这个简单的插入语句在插入过程的经历。主要集中在插入流程和提交流程,不包含前期的其他阶段。
下面是这个语句经历的所有的阶段:

   126  T@2: | THD::enter_stage: 'starting' /root/mysql5.7.14/percona-server-5.7.14-7/sql/conn_handler/socket_connection.cc:100
   349  T@2: | | | | | | THD::enter_stage: 'checking permissions' /root/mysql5.7.14/percona-server-5.7.14-7/sql/auth/sql_authorization.cc:843
   359  T@2: | | | | | | | THD::enter_stage: 'Opening tables' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_base.cc:5719
  1078  T@2: | | | | | THD::enter_stage: 'init' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_insert.cc:470
  1155  T@2: | | | | | | | THD::enter_stage: 'System lock' /root/mysql5.7.14/percona-server-5.7.14-7/sql/lock.cc:321
  1253  T@2: | | | | | THD::enter_stage: 'update' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_insert.cc:663
  1535  T@2: | | | | | THD::enter_stage: 'end' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_insert.cc:881
  1544  T@2: | | | | THD::enter_stage: 'query end' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:5174
  1603  T@2: | | | | THD::enter_stage: 'closing tables' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:5252
  1730  T@2: | | | THD::enter_stage: 'freeing items' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:5855
  1793  T@2: | | THD::enter_stage: 'cleaning up' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:1884
  1824  T@2: | THD::enter_stage: 'starting' /root/mysql5.7.14/percona-server-5.7.14-7/sql/conn_handler/socket_connection.cc:100

主要集中在:

  • update
  • query end

两个阶段

二、大概流程

1、乐观插入的流程
Sql_cmd_insert::mysql_insert
 >Sql_cmd_insert::mysql_insert
    >切换session状态为 update
    >进入插入逻辑
    >handler::ha_write_row
     >ha_innobase::write_row
      >row_insert_for_mysql
            >row_insert_for_mysql_using_ins_graph 
             >trx_start_if_not_started_xa_low 
               >trx_start_low                                       激活事物,事物状态由 not_active 变为 active
             >row_ins_step
               >row_ins
                >row_ins_index_entry_step
                 >row_ins_index_entry
                  >row_ins_clust_index_entry
                            >row_ins_clust_index_entry_low 
                              >btr_cur_search_to_nth_level                   查找定位数据
                               >btr_cur_optimistic_insert                    进行乐观插入
                                 >btr_cur_ins_lock_and_undo 
                                  >trx_undo_report_row_operation 
                                     >trx_undo_page_report_insert               记录insert的undo记录
                                      >trx_undo_page_set_next_prev_and_add
                                       >trx_undof_page_add_undo_rec_log         记录undo的redo log 入redo buffer
                                 >page_cur_tuple_insert                      进行insert 元组插入,及实际的插入操作
                                  >page_cur_insert_rec_write_log             记录插入的redo log 入redo buffer                     
       >binlog_log_row    
        >write_locked_table_maps 
         >THD::binlog_write_table_map
          >binlog_start_trans_and_stmt
           >binlog_cache_data::write_event                        binlog event 写入到 binlog cache    
2、其提交流程
进入提交逻辑  
mysql_execute_command
 >切换session状态为 query end
 >trans_commit_stmt
  >ha_commit_trans
   >MYSQL_BIN_LOG::prepare
    >ha_prepare_low
        >binlog_prepare                                         生成last_commit
     >innobase_xa_prepare
      >trx_prepare_for_mysql
       >trx_prepare                                            转换事物状态为,事物状态由 active 变为 prepare
   >MYSQL_BIN_LOG::commit
    >MYSQL_BIN_LOG::ordered_commit
     >MYSQL_BIN_LOG::process_flush_stage_queue
      >ha_flush_logs
       >plugin_foreach_with_mask
        >flush_handlerton
         >innobase_flush_logs
          >log_buffer_flush_to_disk
           >log_write_up_to
            >log_group_write_buf                               innodb 组提交,确保redo落盘
      >MYSQL_BIN_LOG::flush_thread_caches
       >binlog_cache_mngr::flush
        >binlog_cache_data::flush                              binlog cache 进行flush到binlog文件
      >MYSQL_BIN_LOG::sync_binlog_file                         fsync binlog文件进行os缓存落盘
      >MYSQL_BIN_LOG::process_commit_stage_queue
       >ha_commit_low
        >innobase_commit
         >innobase_commit_low                                   
          >trx_commit_in_memory                                innodb 进行提交,事物状态由 prepare 变为 not_active

可以看到整个语句的流程大概为

  1. 会话状态转换为update
  2. 激活事物状态由 not_active 变为 active
  3. 查找定位数据
  4. 进行乐观插入

    • 记录insert的undo记录
    • 记录undo的redo log 入redo buffer
    • 进行insert 元组插入,及实际的插入操作
  • 记录插入的redo log 入redo buffer
binlog event 写入到 binlog cache会话状态转换为query end

进入提交准备

  • binlog准备
  • innodb层事物准备,状态由 active变为 prepare

进入提交阶段

  • innodb进行组提交,确保redo落盘
  • binlog cache 进行flush到binlog文件
  • fsync binlog文件进行os缓存落盘
  • innodb 进行提交,事物状态由 prepare 变为 not_active

这只是大概流程其中很多很多的细节,不过有了入口函数也许好分析一些。

三、备用栈帧

Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000ebd5f3 in main(int, char**) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/main.cc:25
       breakpoint already hit 1 time
5       breakpoint     keep y   0x0000000001a90776 in page_cur_insert_rec_write_log(rec_t*, ulint, rec_t*, dict_index_t*, mtr_t*)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/page/page0cur.cc:964
       breakpoint already hit 7 times
8       breakpoint     keep y   0x0000000001bc8f96 in trx_undo_page_report_insert(ib_page_t*, trx_t*, dict_index_t*, dtuple_t const*, mtr_t*)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/trx/trx0rec.cc:478
       breakpoint already hit 5 times
9       breakpoint     keep y   0x0000000001bc84c4 in trx_undof_page_add_undo_rec_log(ib_page_t*, ulint, ulint, mtr_t*)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/trx/trx0rec.cc:67
       breakpoint already hit 20 times
10      breakpoint     keep y   0x00000000019a932d in innobase_start_trx_and_assign_read_view(handlerton*, THD*)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:4499
11      breakpoint     keep y   0x0000000001bddbfc in trx_start_low(trx_t*, bool) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/trx/trx0trx.cc:1380
       breakpoint already hit 3 times
12      breakpoint     keep y   0x0000000001c1e9eb in btr_cur_search_to_nth_level(dict_index_t*, ulint, dtuple_t const*, page_cur_mode_t, ulint, btr_cur_t*, ulint, char const*, ulint, mtr_t*) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/btr/btr0cur.cc:770
       breakpoint already hit 13 times
13      breakpoint     keep y   0x0000000001859c85 in binlog_start_trans_and_stmt(THD*, Log_event*) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9737
       breakpoint already hit 1 time
14      breakpoint     keep y   0x0000000001845822 in binlog_cache_data::write_event(THD*, Log_event*) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:1114
       breakpoint already hit 3 times
15      breakpoint     keep y   0x000000000153a2a3 in THD::enter_stage(PSI_stage_info const*, PSI_stage_info*, char const*, char const*, unsigned int)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_class.cc:732
       breakpoint already hit 8 times
17      breakpoint     keep y   0x0000000001be195a in trx_prepare(trx_t*) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/trx/trx0trx.cc:2947
       breakpoint already hit 3 times
19      breakpoint     keep y   0x0000000000f63801 in ha_commit_trans(THD*, bool, bool) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:1684
       breakpoint already hit 21 times
21      breakpoint     keep y   0x0000000001846901 in binlog_prepare(handlerton*, THD*, bool) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:1578
       breakpoint already hit 3 times
24      breakpoint     keep y   0x00000000019c2c64 in innobase_xa_prepare(handlerton*, THD*, bool)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:17458
       breakpoint already hit 2 times
25      breakpoint     keep y   0x00000000019a9788 in innobase_commit(handlerton*, THD*, bool)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:4652
       breakpoint already hit 2 times
26      breakpoint     keep y   0x0000000001846442 in binlog_cache_data::flush(THD*, my_off_t*, bool*) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:1408
       breakpoint already hit 2 times
27      breakpoint     keep y   0x0000000001857c19 in MYSQL_BIN_LOG::sync_binlog_file(bool) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8802
       breakpoint already hit 1 time
28      breakpoint     keep y   0x0000000001bdf2f5 in trx_commit_in_memory(trx_t*, mtr_t const*, bool)
                                              at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/trx/trx0trx.cc:1973

作者微信:
微信.jpg

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
SQL 存储 缓存
MySQL执行流程
本文介绍了MySQL的执行流程,分为server层和引擎层。server层包含连接器、查询缓存、解析器、预处理器、优化器等组件,负责SQL的接收、解析、优化及执行;引擎层负责数据的存储与读取。文章详细解释了各组件的功能,如连接器负责用户身份认证,查询缓存提高查询效率,解析器进行SQL的词法和语法分析,预处理器验证表和字段的存在性,优化器选择最优执行计划,最终由查询执行引擎完成查询并将结果返回给客户端。
296 0
MySQL执行流程
|
10月前
|
SQL 算法 搜索推荐
mysql 之order by工作流程
本文深入解析了MySQL中`ORDER BY`的排序机制,通过具体示例展示了排序过程及性能优化方法。文章首先分析了基于内存和磁盘的排序方式,包括`sort_buffer_size`的影响以及临时文件的使用场景。接着介绍了`rowid`排序算法,该算法通过减少参与排序的数据量来提升性能,并对比了其与传统排序的区别。此外,还探讨了随机查询`ORDER BY RAND()`的执行流程及其优化策略。最后提到了MySQL 5.6引入的优先队列排序算法,适用于仅需部分有序结果的场景。文章结合`optimizer_trace`工具详细说明了各配置参数对排序行为的影响,为优化查询提供了实用指导。
164 1
mysql 之order by工作流程
|
存储 SQL NoSQL
|
SQL 缓存 关系型数据库
揭秘MySQL一条SQL语句的执行流程
以上步骤共同构成了MySQL处理SQL语句的完整流程,理解这一流程有助于更有效地使用MySQL数据库,优化查询性能,及时解决可能出现的性能瓶颈问题。
338 8
|
存储 自然语言处理 关系型数据库
MySQL全文索引源码剖析之Insert语句执行过程
【8月更文挑战第17天】在MySQL中,处理含全文索引的`INSERT`语句涉及多步骤。首先进行语法解析确认语句结构无误;接着语义分析检查数据是否符合表结构及约束。随后存储引擎执行插入操作,若涉及全文索引则进行分词处理,并更新倒排索引结构。此外,事务管理确保了操作的完整性和一致性。通过示例创建含全文索引的表并插入数据,可见MySQL如何高效地处理此类操作,有助于优化数据库性能和提升全文搜索效果。
220 2
|
SQL 关系型数据库 MySQL
SQL语句编写的练习(MySQL)
这篇文章提供了MySQL数据库中关于学生表、课程表、成绩表和教师表的建表语句、数据插入示例以及一系列SQL查询练习,包括查询、排序、聚合和连接查询等操作。
|
关系型数据库 MySQL
解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
解决MySQL insert出现Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘xxx‘ at row 1
1292 2
|
存储 关系型数据库 MySQL
在 MySQL 中使用 Insert Into Select
【8月更文挑战第11天】
5722 0
在 MySQL 中使用 Insert Into Select
|
NoSQL Java Redis
软件开发常见流程之宝塔初始化安装环境配置,Lam前面不选,直接跳商城,在宝塔内点击软件商城,安Mysql5.7,安java项目管理器,安Ngnix最新版,安Redis
软件开发常见流程之宝塔初始化安装环境配置,Lam前面不选,直接跳商城,在宝塔内点击软件商城,安Mysql5.7,安java项目管理器,安Ngnix最新版,安Redis
|
SQL 安全 关系型数据库
MySQL DML语句insert全表数据添加语句以及注意事项
MySQL DML语句insert全表数据添加语句以及注意事项
295 0

推荐镜像

更多