码迷,mamicode.com
首页 > 数据库 > 详细

初看mysql源代码之mysql.cc

时间:2016-05-17 11:32:08      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:

在mysql的源代码目录中,sql目录是mysql源代码中经常变化的目录之一,也是MySQL服务器内核最为核心和重要的目录。

sql目录除了包含mysqld.cc这一MySQL main函数所在文件外,还包括了各类SQL语句的解析/实现。

 

在sql目录下的main.cc里面就调用了一个mysqld_main(),但是mysql里面好像有一个win_main()和mysqld_main(),

当时我就比较奇怪,刚好一个对应于windows一个对应于linux下的呀。当时想了半天,没搞明白。后来又看了一遍mysqld_main.cc,才有点看明白了。

 

实际上在windows下和linuxmysql服务器启动的环境和方式是不一样的,但是mysql为了偷懒只搞了一套源代码,这样发布项目的时候是方便了,尼玛windows和linux只要一套源代码就行了,但是读起来错综复杂的,各种条件编译命令眼花缭乱,让你看不清真相。

mysql在windows和linux上启动服务的过程有一部分代码是相似的,这一部分代码就根据是否定义了_WIN32来决定是命名为win_main()还是mysqld_main();如果是命名为win_main()那么我们在后面还要有一个mysqld_main()来调用这个win_main(),而如果是mysqld_main(),那么后面另外一个mysqld_main()就不需要再定义了。

#ifdef _WIN32	// 如果定义了_WIN32,则会编译win_main()
int win_main(int argc, char **argv)
#else
int mysqld_main(int argc, char **argv)	// 如果没有定义了_WIN32,则会编译mysqld_main()
{
	// 这个是windows上和linux服务器启动时代码相同的部分
	// 当然里面也有很多的编译预处理命令
}
#endif

#if defined(_WIN32)
int mysqld_main(int argc, char **argv)
{
	// 这里是用于windows上的mysqld_main();
}
#endif // _WIN32     这个endif对应于 5021行的if defined(_WIN32)

就是这几个编译命令决定了是走向windows还是linux,下面我们再来看看mysqld_main()是如何调用win_main()的,

如果你在mysqld_main()直接找win_main()那是找不到滴,这里呢在有个函数叫mysql_service(void *p):

#if defined(_WIN32)				// 如果定义了_WIN32   
int mysql_service(void *p)	// 居然是在这儿调用了win_main()
{
  if (my_thread_init())
  {
    flush_error_log_messages();
    return 1;
  }

  if (use_opt_args)
    win_main(opt_argc, opt_argv);	// 对于win_main()的调用
  else
    win_main(Service.my_argc, Service.my_argv);// 对于win_main()的调用

  my_thread_end();
  return 0;
}

哈哈,找到了对win_main()的调用,所以可以肯定mysqld_main()里面也调用了mysql_service(void *p):

找找看,果真有

if (Service.GetOS())  /* true NT family */		// 也就是说这个是用于NT上的
{
	char file_path[FN_REFLEN];
    my_path(file_path, argv[0], "");          /* Find name in path */
    fn_format(file_path,argv[0],file_path,"",
              MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);

    if (argc == 2)
    {
		if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
                                    file_path, "", NULL))
			return 0;
		if (Service.IsService(argv[1]))        /* Start an optional service */
		{
			/*
				Only add the service name to the groups read from the config file
				if it‘s not "MySQL". (The default service name should be ‘mysqld‘
				but we started a bad tradition by calling it MySQL from the start
				and we are now stuck with it.
			*/
			if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
				load_default_groups[load_default_groups_sz-2]= argv[1];
			windows_service= true;
			Service.Init(argv[1], mysql_service);	// 这个里面调用了mysql_service,也就是说会间接的调用到win_main()
			return 0;
		}
    }
    else if (argc == 3) /* install or remove any optional service */
    {
		if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
                                    NULL))
			return 0;
		if (Service.IsService(argv[2]))
		{
			/*
				mysqld was started as
				mysqld --defaults-file=my_path\my.ini service-name
			*/
			use_opt_args=1;
			opt_argc= 2;        // Skip service-name
			opt_argv=argv;
			windows_service= true;
			if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
				load_default_groups[load_default_groups_sz-2]= argv[2];
			Service.Init(argv[2], mysql_service);
			// 这个里面调用了mysql_service,也就是说会间接的调用到win_main()
			return 0;
		}
    }
    else if (argc == 4 || argc == 5)
    {
		/*
			This may seem strange, because we handle --local-service while
			preserving 4.1‘s behavior of allowing any one other argument that is
			passed to the service on startup. (The assumption is that this is
			--defaults-file=file, but that was not enforced in 4.1, so we don‘t
			enforce it here.)
		*/
		const char *extra_opt= NullS;
		const char *account_name = NullS;
		int index;
		for (index = 3; index < argc; index++)
		{
			if (!strcmp(argv[index], "--local-service"))
				account_name= "NT AUTHORITY\\LocalService";
			else
			extra_opt= argv[index];
		}

		if (argc == 4 || account_name)
			if (!default_service_handling(argv, argv[2], argv[2], file_path,
                                      extra_opt, account_name))
				return 0;
	}
    else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
    {
		/* start the default service */
		windows_service= true;
		Service.Init(MYSQL_SERVICENAME, mysql_service);
		// 这个里面调用了mysql_service,也就是说会间接的调用到win_main()
		return 0;
    }
}

就看了这一点先写这么多?

初看mysql源代码之mysql.cc

标签:

原文地址:http://www.cnblogs.com/tuhooo/p/5500713.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!