当有客户端发送命令道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.cc
void 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.cc
bool 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.cc
bool 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.cc
bool 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;
}
}
mysql 执行命令的过程
最新推荐文章于 2024-08-20 09:17:28 发布