为了研究SELECT * FROM xx 语句查询慢的本质原因,打算从Mysql源码看起,探查SELECT语句的执行流程。本次就成mysqld启动开始查看。
本文以Mysql-5.7.19版本来进行研究。
我们都知道C/C++都是从main函数开始调用, 可以从sql/main.cc开始看起。
int main(int argc, char **argv)
{
return mysqld_main(argc, argv);
}
继续查看mysqld_main定义,发现sql/mysqld.cc有两个mysqld_main函数定义。
第一处定义4361行开始。
#ifdef _WIN32
int win_main(int argc, char **argv)
#else
int mysqld_main(int argc, char **argv)
#endif
{
/*
Perform basic thread library and malloc initialization,
to be able to read defaults files and parse options.
*/
my_progname= argv[0];
// more ...
}
第二处定义5214行开始。
int mysqld_main(int argc, char **argv)
{
/*
When several instances are running on the same machine, we
need to have an unique named hEventShudown through the
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/
int10_to_str((int) GetCurrentProcessId(),my_stpcpy(shutdown_event_name,
"MySQLShutdown"), 10);
// more...
mysql_service(NULL);
return 0;
}
看到这里就比较好奇怎么出现了两个mysqld_main函数定义。经过查阅资料及细看代码,发现第二处的函数定义其实最外层有一层逻辑判断。从5106行代码开始看。
/****************************************************************************
Main and thread entry function for Win32
(all this is needed only to run mysqld as a service on WinNT)
****************************************************************************/
#if defined(_WIN32)
int mysql_service(void *p)
{
if (my_thread_init())
{
flush_error_log_messages();
return 1;
}
if (use_opt_args)
win_main(opt_argc, opt_argv);
else
win_main(Service.my_argc, Service.my_argv);
my_thread_end();
return 0;
}
这里有判断#if defined(_WIN32)判断win32平台才会有下面的mysqld_main函数定义。而第一处的mysqld_main判断是win32平台函数名为win_main。不存在定义重复问题。
查阅资料发现,Mysql为了实现可以在win32平台与类Uninx平台代码共用,将一些公用的函数抽象出来,但是win32和类unix平台启动方式不一样。细看win32的mysqld_main调用了mysql_service,mysql_service又调用了win_main函数,经过特殊操作处理后又回到了最初公共定义。