简单记录,可能有误,主要记录重要的接口以备后用。
一、操作说明
我建了一个简单的表,插入一个简单的数据。
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
可以看到整个语句的流程大概为
- 会话状态转换为update
- 激活事物状态由 not_active 变为 active
- 查找定位数据
-
进行乐观插入