MySQL 源码导读 5.7


mysql 主要脉络 (看c/c++ 建议使用QT)


文件  函数
1.sql->mysqld.cc(这是整个MySQL的入口)  mysqld_socket_acceptor->connection_event_loop();
2.sql/conn_handler->connection_handler_manager.cc m_connection_handler->add_connection(channel_info)
3.sql/conn_handler->connection_handler_per_thread.cc   error= mysql_thread_create(key_thread_one_connection, &id,
                             &connection_attrib,
                             handle_connection,
                             (void*) channel_info);
4.sql->sql_parse.cc  do_command(thd)
5.sql->sql_parse.cc  return_value= dispatch_command(thd, &com_data, command);
6.sql->sql_parse.cc  mysql_parse(thd, &parser_state);
7.sql->sql_parse.cc  error= mysql_execute_command(thd, true);
8.sql->sql_parse.cc   res= execute_sqlcom_select(thd, all_tables);
9.sql->sql_parse.cc   res= handle_query(thd, lex, result, 0, 0); select->join->exec();
10.sql->sql_select.cc   select->join->exec();


extern "C" void *handle_connection(void *arg)
{
  
    ...
    {
      while (thd_connection_alive(thd))
      {
        if (do_command(thd))
          break;
      }
      end_connection(thd);
    }
    ....
}



bool dispatch_command(THD *thd, const COM_DATA *com_data,enum enum_server_command command)
{
  
  ...
  switch (command) {
  case COM_INIT_DB:
  {
  ...
  case COM_QUERY:
  {
    DBUG_ASSERT(thd->m_digest == NULL);
    thd->m_digest= & thd->m_digest_state;
    thd->m_digest->reset(thd->m_token_array, max_digest_length);

    if (alloc_query(thd, com_data->com_query.query,
                    com_data->com_query.length))
      break;					// fatal error is set
    MYSQL_QUERY_START(const_cast<char*>(thd->query().str), thd->thread_id(),
                      (char *) (thd->db().str ? thd->db().str : ""),
                      (char *) thd->security_context()->priv_user().str,
                      (char *) thd->security_context()->host_or_ip().str);

    const char *packet_end= thd->query().str + thd->query().length;

    if (opt_general_log_raw)
      query_logger.general_log_write(thd, command, thd->query().str,
                                     thd->query().length);

    DBUG_PRINT("query",("%-.4096s", thd->query().str));

#if defined(ENABLED_PROFILING)
    thd->profiling.set_query_source(thd->query().str, thd->query().length);
#endif

    MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query().str,
                             thd->query().length);

    Parser_state parser_state;
    if (parser_state.init(thd, thd->query().str, thd->query().length))
      break;

    mysql_parse(thd, &parser_state);

    while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) &&
           ! thd->is_error())
    {
      /*
        Multiple queries exits, execute them individually
      */
      const char *beginning_of_next_stmt= parser_state.m_lip.found_semicolon;

      /* Finalize server status flags after executing a statement. */
      thd->update_server_status();
      thd->send_statement_status();
      query_cache.end_of_result(thd);

#ifndef EMBEDDED_LIBRARY
      mysql_audit_general(thd, MYSQL_AUDIT_GENERAL_STATUS,
                          thd->get_stmt_da()->is_error() ?
                          thd->get_stmt_da()->mysql_errno() : 0,
                          command_name[command].str);
#endif

      size_t length= static_cast<size_t>(packet_end - beginning_of_next_stmt);

      log_slow_statement(thd);

      /* Remove garbage at start of query */
      while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
      {
        beginning_of_next_stmt++;
        length--;
      }

/* PSI end */
      MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
      thd->m_statement_psi= NULL;
      thd->m_digest= NULL;

/* DTRACE end */
      if (MYSQL_QUERY_DONE_ENABLED())
      {
        MYSQL_QUERY_DONE(thd->is_error());
      }

/* SHOW PROFILE end */
#if defined(ENABLED_PROFILING)
      thd->profiling.finish_current_query();
#endif

/* SHOW PROFILE begin */
#if defined(ENABLED_PROFILING)
      thd->profiling.start_new_query("continuing");
      thd->profiling.set_query_source(beginning_of_next_stmt, length);
#endif

/* DTRACE begin */
      MYSQL_QUERY_START(const_cast<char*>(beginning_of_next_stmt),
                        thd->thread_id(),
                        (char *) (thd->db().str ? thd->db().str : ""),
                        (char *) thd->security_context()->priv_user().str,
                        (char *) thd->security_context()->host_or_ip().str);

/* PSI begin */
      thd->m_digest= & thd->m_digest_state;

      thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
                                          com_statement_info[command].m_key,
                                          thd->db().str, thd->db().length,
                                          thd->charset(), NULL);
      THD_STAGE_INFO(thd, stage_starting);
      MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, beginning_of_next_stmt, length);

      thd->set_query(beginning_of_next_stmt, length);
      thd->set_query_id(next_query_id());
      /*
        Count each statement from the client.
      */
      thd->status_var.questions++;
      thd->set_time(); /* Reset the query start time. */
      parser_state.reset(beginning_of_next_stmt, length);
      /* TODO: set thd->lex->sql_command to SQLCOM_END here */
      mysql_parse(thd, &parser_state);
    }

    /* Need to set error to true for graceful shutdown */
    if((thd->lex->sql_command == SQLCOM_SHUTDOWN) && (thd->get_stmt_da()->is_ok()))
      error= TRUE;

    DBUG_PRINT("info",("query ready"));
    break;
  }
  
  ...

  thd->send_statement_status(); //网络返回
  thd->rpl_thd_ctx.session_gtids_ctx().notify_after_response_packet(thd);
  query_cache.end_of_result(thd);

  ...
}




 

猜你喜欢

转载自blog.csdn.net/qq948993066/article/details/77853054