mysql源码笔记【SQL执行流程】

174 阅读1分钟
create table ddl_test(id int  primary key,  name varchar(10));

mysql.taobao.org/monthly/202… 此文中可见btr_cur_search_to_nth_level() 是sql执行路径中与Innodb索引页打交道的入口,在这打个断点得到以下堆栈

image.png

转换成(待补充)时序图是

sequenceDiagram
participant pfs as /storage/perfschema/pfs.cc
participant con_handle_thread as connection_handle_per_thread.cc
participant sql_parse as sql_parse.cc
participant sql_cmd_ddl_table as sql_cmd_ddl_table.cc
participant sql_table as sql_table.cc
participant sql_base_header as sql_base.h
participant sql_base as sql_base.cc
participant dd_table as dd_table.cc
participant dict_client as cache/dictionary_client.cc
participant share_dict_cache as cache/shared_dictionary_cache.cc
participant storage_adapter_header as cache/storage_adapter.h
participant storage_adapter as cache/storage_adapter.cc

participant raw_table as raw/raw_table.cc
participant handler_header as sql/handler.h
participant handler as sql/handler.cc
participant ha_innodb as innobase/handler/ha_innodb.cc
participant row0sel as innobase/row/row0sel.cc
participant btr0pcur_header as btr0pcur.h
participant btr0cur.cc as innobase/btr/btr0cur.cc
participant ERROR 

pfs->>pfs: pfs_spawn_thread()
pfs->>con_handle_thread: handle_connection(void *arg)
con_handle_thread->>sql_parse: do_command()
sql_parse->>sql_parse: dispatch_command()
sql_parse->>sql_parse: mysql_excute_command()
sql_parse->>sql_cmd_ddl_table: 3577行调用了 Sql_cmd_create_table:excute()
sql_cmd_ddl_table->>sql_table: 433行调用了 mysql_create_table() 
sql_table->>sql_base_header: 10013行调用了 不带阻塞策略open_tables() 
sql_base_header->>sql_base: 455行调用了 带阻塞策略open_table() 
sql_base->>sql_base: 5854行调用了 open_and_process_table() 
sql_base->>sql_base: 5051行调用了 open_table() 
sql_base->>sql_base: 3105行调用了 check_if_table_exists() 
sql_base->>dd_table: 2504行调用了 dd:table_exists(client,name,name,true/false exists) 
dd_table->>dict_client: 2455行调用了 acquire() 
dict_client->>dict_client: 1378行调用了 内部acquire(key,**ojbect ... )
dict_client->>share_dict_cache: 909 Shared_dictionary_cache::instance()->get()
share_dict_cache->>share_dict_cache: 存在表的话 98行get_uncached()
share_dict_cache->>ERROR: 已存在表
share_dict_cache->>storage_adapter: 113行调用了Storage_adapter::get(...)
storage_adapter->>raw_table: 181行调用了find_reecord()
raw_table->>handler: 78行调用了ha_index_read_idx_map()
handler->>handler: 7419行调用了index_read_map()
handler->>handler_header: 5282行调用了“虚方法”index_read()
handelr_header->>row0sel: 10269行调用了row_search_mvcc()
row0sel->>btr0pcur_header: 4842行调用了pcur->open_no_init()
btr0pcur_header->> btr0cur:(如果非内置表)616行调用了btr_cur_search_to_nth_level()



// Some code
reopen_fstreams()函数在5.6版本被去掉,为了修复bug#29751 https://bugs.mysql.com/bug.php?id=29751

```cpp
// 创建“句柄管理器” 后面在《运维内存》里面说的是handle_connections_sockets() 
// 来创建socket连接句柄 根据代码追踪并不是
// 代码如下
#if defined(_WIN32)
  setup_conn_event_handler_threads();
#else
  mysql_mutex_lock(&LOCK_socket_listener_active);
  // Make it possible for the signal handler to kill the listener.
  socket_listener_active= true;
  mysql_mutex_unlock(&LOCK_socket_listener_active);

  if (opt_daemonize)
    mysqld::runtime::signal_parent(pipe_write_fd,1);
   // 事件循环
  mysqld_socket_acceptor->connection_event_loop();
#endif /* _WIN32 */
// 连接分三种 命名管道、共享内存、套接字 ,常用的是套接字 以下2个函数分别是其逻辑

// 套接字连接方式
extern "C" void *socket_conn_event_handler(void *arg) {  
my_thread_init();  
  
Connection_acceptor<Mysqld_socket_listener> *conn_acceptor =  
static_cast<Connection_acceptor<Mysqld_socket_listener> *>(arg);  
conn_acceptor->connection_event_loop();  
  
decrement_handler_count();  
my_thread_end();  
return 0;  
}

// 命令管道连接方式
extern "C" void *named_pipe_conn_event_handler(void *arg)
{
  my_thread_init();

  Connection_acceptor<Named_pipe_listener> *conn_acceptor=
    static_cast<Connection_acceptor<Named_pipe_listener>*>(arg);
  conn_acceptor->connection_event_loop();

  decrement_handler_count();
  my_thread_end();
  return 0;
}
// 共享内存连接方式
extern "C" void *shared_mem_conn_event_handler(void *arg)
{
  my_thread_init();

  Connection_acceptor<Shared_mem_listener> *conn_acceptor=
    static_cast<Connection_acceptor<Shared_mem_listener>*>(arg);
  conn_acceptor->connection_event_loop();

  decrement_handler_count();
  my_thread_end();
  return 0;
}
/**
    三种连接方式中 共同逻辑:处理链接请求
    Connection acceptor loop to accept connections from clients.
  */
  void connection_event_loop()
  {
    Connection_handler_manager *mgr= Connection_handler_manager::get_instance();
    while (!abort_loop)
    {
      Channel_info *channel_info= m_listener->listen_for_connection_event();
      if (channel_info != NULL)
        mgr->process_new_connection(channel_info);
    }
  }

天啊 ! 时序图这样子把眼睛看瞎也看不清 谁知道怎么方大吗?在线求助。