mysql监听怎么启动_mysql 5.7源码 启动监听过程

MySQL启动

主要代码在sql/mysqld.cc中,精简后的代码如下:

int main(int argc, char **argv) //标准入口函数

MY_INIT(argv[0]); //调用mysys/My_init.c->my_init(),初始化mysql内部的系统库

logger.init_base(); //初始化日志功能

init_common_variables(MYSQL_CONFIG_NAME,argc, argv, load_default_groups) //调用load_defaults(conf_file_name, groups, &argc, &argv),读取配置信息

user_info= check_user(mysqld_user);//检测启动时的用户选项

set_user(mysqld_user, user_info);//设置以该用户运行

init_server_components();//初始化内部的一些组件,如table_cache, query_cache等。

network_init();//初始化网络模块,创建socket监听

start_signal_handler();// 创建pid文件

mysql_rm_tmp_tables() || acl_init(opt_noacl)//删除tmp_table并初始化数据库级别的权限。

init_status_vars(); // 初始化mysql中的status变量

start_handle_manager();//创建manager线程

handle_connections_sockets();//主要处理函数,处理新的连接并创建新的线程处理之

监听接收链接

主要代码在sql/mysqld.cc中,精简后的代码如下:

THD *thd;

FD_SET(ip_sock,&clientFDs); //客户端socket

while (!abort_loop)

readFDs=clientFDs;

if (select((int) max_used_connection,&readFDs,0,0,0) error && net->vio != 0 &&

!(thd->killed == THD::KILL_CONNECTION))

{

if(do_command(thd)) //处理客户端发出的命令

break;

}

end_connection(thd);

}

预处理连接

thread_count++;//增加当前连接的线程

thread_scheduler.add_connection(thd);

for (;;) {

lex_start(thd);

login_connection(thd); // 认证

prepare_new_connection_state(thd); //初始化thd描述符

while(!net->error && net->vio != 0 &&

!(thd->killed == THD::KILL_CONNECTION))

{

if(do_command(thd)) //处理客户端发出的命令

break;

}

end_connection(thd);

}

处理

do_command在sql/sql_parse.cc中:读取客户端传递的命令并分发。

NET *net= &thd->net;

packet_length= my_net_read(net);

packet= (char*) net->read_pos;

command= (enum enum_server_command) (uchar) packet[0]; //从net结构中获取命令

dispatch_command(command, thd, packet+1, (uint) (packet_length-1));//分发命令

在dispatch_command函数中,根据命令的类型进行分发。

thd->command=command;

switch( command ) {

case COM_INIT_DB: ...;

case COM_TABLE_DUMP: ...;

case COM_CHANGE_USER: ...;

….

case COM_QUERY: //如果是查询语句

{

alloc_query(thd, packet, packet_length)//thd->set_query(query, packet_length);

mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);

// 解析查询语句

….

}

在mysql_parse函数中,

lex_start(thd);

if (query_cache_send_result_to_client(thd, (char*) inBuf, length) sql_command

在mysql_execute_command中,根据命令类型,转到相应的执行函数。

switch (lex->sql_command) {

LEX *lex= thd->lex;

TABLE_LIST *all_tables;

case SQLCOM_SELECT:

check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, all_tables, UINT_MAX, FALSE); //检查用户权限

execute_sqlcom_select(thd, all_tables); //执行select命令

break;

case SQLCOM_INSERT:

{ res= insert_precheck(thd, all_tables) //rights

mysql_insert(thd, all_tables, lex->field_list, lex->many_values,

lex->update_list, lex->value_list,

lex->duplicates, lex->ignore);

break;

在execute_sqlcom_select函数中,

res= open_and_lock_tables(thd, all_tables)//directly and indirectly

res= handle_select(thd, lex, result, 0);

handle_select在sql_select.cc中,调用mysql_select ,在mysql_select中,

join->prepare();//Prepare of whole select (including sub queries in future).

join->optimize();//global select optimisation.

join->exec();//

在mysql_insert函数中,

open_and_lock_tables(thd, table_list)

mysql_prepare_insert(); //prepare item in INSERT statment

while ((values= its++))

write_record(thd, table ,&info);//写入新的数据

在write_record函数中,

table->file->ha_write_row(table->record[0])

ha_write_row在Handler.cc中,只是一个接口

write_row(buf); //调用表存储所用的引擎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值