博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mysql 执行命令的过程
阅读量:4215 次
发布时间:2019-05-26

本文共 3945 字,大约阅读时间需要 13 分钟。

当有客户端发送命令道mysqld的时候,会在下面函数中接受命令mysql-server\sql\conn_handler\connection_acceptor.h中的  /**    Connection acceptor loop to accept connections from clients.  */  void connection_event_loop() {    Connection_handler_manager *mgr =        Connection_handler_manager::get_instance();    while (!connection_events_loop_aborted()) {      Channel_info *channel_info = m_listener->listen_for_connection_event();				#建立新的连接      if (channel_info != NULL) mgr->process_new_connection(channel_info);    }  }mysql-server\sql\conn_handler\connection_handler_manager.ccvoid Connection_handler_manager::process_new_connection(    Channel_info *channel_info) {  if (connection_events_loop_aborted() || !check_and_incr_conn_count()) {    channel_info->send_error_and_close_channel(ER_CON_COUNT_ERROR, 0, true);    delete channel_info;    return;  }#通过add_connection函数负责添加连接  if (m_connection_handler->add_connection(channel_info)) {    inc_aborted_connects();    delete channel_info;  }}这里注意  virtual bool add_connection(Channel_info *channel_info) = 0; 是一个虚函数这个虚函数有两个实现mysql-server\sql\conn_handler\connection_handler_impl.h  Per_thread_connection_handler() {}  virtual ~Per_thread_connection_handler() {} protected:  virtual bool add_connection(Channel_info *channel_info);  virtual uint get_max_threads() const;};/**  This class represents the connection handling functionality  of all connections being handled in a single worker thread.*/class One_thread_connection_handler : public Connection_handler {  One_thread_connection_handler(const One_thread_connection_handler &);  One_thread_connection_handler &operator=(      const One_thread_connection_handler &); public:  One_thread_connection_handler() {}  virtual ~One_thread_connection_handler() {} protected:  virtual bool add_connection(Channel_info *channel_info);  virtual uint get_max_threads() const { return 1; }};这里以Per_thread_connection_handler中的实现为例mysql-server\sql\conn_handler\connection_handler_per_thread.ccbool Per_thread_connection_handler::add_connection(Channel_info *channel_info) {  int error = 0;  my_thread_handle id;  /*    There are no idle threads avaliable to take up the new    connection. Create a new thread to handle the connection  */  channel_info->set_prior_thr_create_utime();#进行线程的创建,这里的回调函数是handle_connection,   error =      mysql_thread_create(key_thread_one_connection, &id, &connection_attrib,                          handle_connection, (void *)channel_info);  Global_THD_manager::get_instance()->inc_thread_created();  DBUG_PRINT("info", ("Thread created"));  DBUG_RETURN(false);}handle_connection同样在当前文件中实现static void *handle_connection(void *arg) {  Global_THD_manager *thd_manager = Global_THD_manager::get_instance();    if (thd_prepare_connection(thd))      handler_manager->inc_aborted_connects();    else {      while (thd_connection_alive(thd)) {#调用do_command来处理客户端发送过来的sql语句        if (do_command(thd)) break;      }      end_connection(thd);    }mysql-server\sql\sql_parse.ccbool do_command(THD *thd) {#调用dispatch_command 来进行命令的分发  return_value = dispatch_command(thd, &com_data, command);  thd->get_protocol_classic()->get_output_packet()->shrink(      thd->variables.net_buffer_length);}mysql-server\sql\sql_parse.ccbool dispatch_command(THD *thd, const COM_DATA *com_data,                      enum enum_server_command command) {  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);      Parser_state parser_state;      if (parser_state.init(thd, thd->query().str, thd->query().length)) break;	#进行命令的解析      mysql_parse(thd, &parser_state);}void mysql_parse(THD *thd, Parser_state *parser_state) {#对解析完的命令进行执行error = mysql_execute_command(thd, true);int mysql_execute_command(THD *thd, bool first_level) {case SQLCOM_SELECT:     DBUG_ASSERT(lex->m_sql_cmd != nullptr);#下面就是对个个指令的执行      res = lex->m_sql_cmd->execute(thd);      break;}}

转载地址:http://ninmi.baihongyu.com/

你可能感兴趣的文章
Linux学习之/etc/init.d/functions详解
查看>>
【Big Data 每日一题20180821】Spark中ml和mllib的区别
查看>>
【Big Data 每日一题20181111】为什么有栈内存和堆内存之分
查看>>
【Big Data 每日一题20180828】Maven 中 jar 包的 Snapshot 和 Release 版本区别
查看>>
【Big Data 每日一题20180831】Spark 的 task 数据 locality?
查看>>
【Big Data 每日一题20180923】Structured Streaming 实现思路与实现概述
查看>>
【Big Data 每日一题20180924】Structured Streaming 之 Source 解析
查看>>
【Big Data 每日一题20180925】Structured Streaming 之 Sink 解析
查看>>
【Big Data 每日一题20180927】Structured Streaming 之 Event Time 解析
查看>>
【Big Data 每日一题20180928】Structured Streaming 之 Watermark 解析
查看>>
【Big Data 每日一题20180929】Spark DAG概述
查看>>
【Big Data 每日一题 - 20180930】Spark启动时的master参数以及Spark的部署方式
查看>>
【Big Data 每日一题20181001】java 深拷贝 方案 (中英版)
查看>>
JNI Java Native Interface
查看>>
阅读源码的三种境界 (转 码农翻身 微信公众号)
查看>>
All Things OpenTSDB
查看>>
表格存储最佳实践:一种用于存储时间序列数据的表结构设计
查看>>
OpenTSDB介绍
查看>>
OpenTSDB原理系列:元数据模型
查看>>
解密OpenTSDB的表存储优化
查看>>