mysql源码阅读(启动一)

源代码版本和系统

mysql5.7.27
带boost的基于linux系统的源代码

mysqld的启动

尝试源码阅读
入口函数:sql\main.cc

extern int mysqld_main(int argc, char **argv); //告诉编译器,下面是C语言的函数。经常在C++混编的程序中看到

int main(int argc, char **argv)
{
  return mysqld_main(argc, argv); //调用的mysqld函数
}

查看mysqld函数定义:
文件sql\mysqld.cc
发现有三个位置存在mysqld_main方法,其中中间一行是注释

win_main in mysqld.cc (D:\vmshare\mysql-5.7.27\sql) : int mysqld_main(int argc, char **argv)
win_main in mysqld.cc (D:\vmshare\mysql-5.7.27\sql) :   // For windows, my_init() is called from the win specific mysqld_main
mysqld.cc (D:\vmshare\mysql-5.7.27\sql) line 5315 : int mysqld_main(int argc, char **argv)

这个是什么原因?
继续分析源代码:
5315行的部分,可以看到从5312行至5426行,在这个中间部分的mysqld_main函数是条件编译的部分

基本结构为:

#if defined(_WIN32)
中间定义了一部分的函数
int mysqld_main() .....
//也就是说,如若有定义的 _WIN32的部分,则会才会编译这个部分的代码。如果不是windows平台,则是使用的这个部分的代码
#endif //_WIN32

如若有定义的 _WIN32的部分,则会才会编译这个部分的代码。如果不是windows平台,则是使用的这个部分的代码

具体的这一部分代码结构如下 :

#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); //编译的时候,如windows平台,则调用win_main的方法
  else
    win_main(Service.my_argc, Service.my_argv);  

  my_thread_end();
  return 0;
}


/* Quote string if it contains space, else copy */

static char *add_quoted_string(char *to, const char *from, char *to_end)
{
  uint length= (uint) (to_end-to);

  if (!strchr(from, ' '))
    return strmake(to, from, length-1);
  return strxnmov(to, length-1, "\"", from, "\"", NullS);
}


/**
  Handle basic handling of services, like installation and removal.

  @param argv             Pointer to argument list
  @param servicename    Internal name of service
  @param displayname    Display name of service (in taskbar ?)
  @param file_path    Path to this program
  @param startup_option Startup option to mysqld

  @retval
    0   option handled
  @retval
    1   Could not handle option
*/

static bool
default_service_handling(char **argv,
       const char *servicename,
       const char *displayname,
       const char *file_path,
       const char *extra_opt,
       const char *account_name)
{
  省略具体的代码
}


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);

  /* Must be initialized early for comparison of service name */
  system_charset_info= &my_charset_utf8_general_ci;

这中间省略了一部分的代码
  /* Start as standalone server */
  Service.my_argc=argc;
  Service.my_argv=argv;
  mysql_service(NULL);
  return 0;
}
#endif // _WIN32

查看第一个搜索结果的部分
从4420到4432函数开开始

#ifdef _WIN32
int win_main(int argc, char **argv)  如果是windows,则编译成win_main。
#else
int mysqld_main(int argc, char **argv) 如果不是windows,则直接编译成mysqld_main函数
#endif
{
//一些具体的操作
}

通过如上分析,我们采用linux调试的话,其实其源代码编译的过程为:
main.cc(main方法调用mysqld_main) > mysqld.cc(第一个部分4423行左右的mysqld_main) > 执行具体的启动流程

windows的启动流程:
main.cc(main方法调用mysqld_main) > mysqld.cc(通过_WIN32定义,调用的是5315行左右的mysqld_main方法) > mysqld.cc(5315行左右的mysqld_main方法调用mysql_service(NULL)方法 > mysqld.cc(mysql_service方法又调用了win_main方法)> win_main方法,有4420行左右通过_WIN32的宏定义可以条件编译出来 ,从而最终和linux系统的版本进入到一个{}的方法体内部

原理总结
Mysql为了实现可以在win32平台与类Uninx平台代码共用,将一些公用的函数抽象出来,最终程序进入统一的方法体 {},但是win32和类unix平台启动方式不一样。

遗留问题:
条件编译的这个 _WIN32宏是在哪里定义的?需要进一步学习的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值