初看mysql源代码之mysql.cc
在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的更多相关文章
- Win7+VS2010:mysql 源代码编译与调试
win7+vs2010源代码编译mysql 近期因为在实习,工作重点在于一些数据库的开发,为了更好的理解数据库的实现机制.眼下萌生了要研究一下mysql数据库源代码的想法.那么好吧,说干就干.首先我们 ...
- 源代码安装 MySQL 5.6.28
本文内容 创建 MySQL 用户和组 解压 MySQL 源代码包 生成配置安装文件 编译和安装 MySQL 配置文件 创建 MySQL 授权表 MySQL 目录授权 启动 MySQL 验证 MySQL ...
- MySQL 源代码scr.rpm安装的一点注意事项
rpm安装包通常为二进制包(Binary)以及源代码包(Source)两种形式. 在使用源代码方式安装MySQL的时候,官方站点上下载的源代码包通常为scr.rpm格式,而不是直接的tar包.对此,须 ...
- 分析学习MYSQL源代码需要哪些方面的知识呢?
分析学习MYSQL源代码需要哪些方面的知识呢? 哪些书籍或网站对这方面有帮助呢? 60d
- MYSQL源代码编译的变动
Mysql的安装,对于mysql不同版本号的mysql源代码编译方式不一样 5.6.2的版本号開始编译方式已经由 configure 变成了cmake方式 ,相关的新的 编译方式在mysql官网已经提 ...
- Macos 编译运行调试Mysql源代码
准备编译工具Clion 下载地址 工具是macos用的系统 百度云盘下载地址(密码: 7dus) 下载mysql源码 Mysql源码下载地址 下载boost boost下载地址 前期准备工作 MySQ ...
- 一看就懂的MySQL的FreeList机制
Hi,大家好!我是白日梦! 今天我要跟你分享的MySQL话题是:"了解InnoDB的FreeList吗?谈谈看!" 本文是MySQL专题的第 7 篇,共110篇. 一.回顾 前面几 ...
- linux下 yum源、rpm、源代码安装mysql
mysql的安装 一.yum源格式安装mysql 1.将下载的yum包上传到linux上: [root@localhost ~]# ls mysql-community-release-el6-5.n ...
- SQL学习笔记——SQL初入门,Ubuntu下MySQL的安装
刚开始接触sql,于是准备在Ubuntu下学习sql,就跟着itercast的sql教程开始入门了. 下面只是我个人的记录,高手请绕道: 一. 在安装之前,我们可以用下面这个命令通过开放端 ...
随机推荐
- 从一个Idea到产品需要经历哪些阶段?
从一个Idea到产品需要经历哪些阶段? Lkey 07月19日 16:520 现实工作中,不免遇到这样的情况.什么嘛?老板(领导)又有新想法了?又有其他Idea了?心里一阵骂娘xxxxxx.或者产品负 ...
- Python 多进程教程
Python2.6版本中新添了multiprocessing模块.它最初由Jesse Noller和Richard Oudkerk定义在PEP 371中.就像你能通过threading模块衍生线程一样 ...
- 理解Lucene中的Query
Query是一个接口,它有很多实现类. QueryParser是Query解析器,用于将一个字符串解析为一个Query对象,这个Query对象可能属于TermQuery,也可能属于PhraseQuer ...
- 由ConcurrentLinkedQueue扯到线程安全 待整理
前几天项目总是报错,找了下原因. ConcurrentLinkedQueue 本身是一个基于链接节点的无界线程安全队列,你自己调用就不用考虑线程安全了吗? 结论是:原子性操作当然是线程安全的,非原子性 ...
- js常用点
<span onClick="onDetail(this.id,'edit');" style="cursor: hand;color:black;" ...
- MyEclipse和Microsoft Visual Studio常用快捷键
MyEclipse Visual Studio NOTEF5 F11 单步执行 F6 F1 ...
- Snail—OC学习之类别Category
类别就是向类加入一些实用的功能或者方法 利于开发 类能够是系统类.能够是自己定义类 类别跟子类是不一样的.类别仅仅能加入一些方法 属性变量什么的不能够加入 不创建新类,就可以对已有类进行扩展 做项目的 ...
- unity 主循环
在unity官方文档中看到这个图,感觉很有用,各事件的先后时机看得较清楚. 连接:http://docs.unity3d.com/Manual/ExecutionOrder.html
- unity c# script error CS0664: Literal of type double cannot be implicitly converted to type `float'. Add suffix `f' to create a literal of this type
例如在unity c# script中定义 private float x=0.0; 则会报 error CS0664: Literal of type double cannot be implic ...
- 大数问题:求n的阶乘
题目:求100! 这看起来是一个非常简答的问题,递归解之毫无压力 int func(int n){ if(n <= 1) return 1; else return n*func(n-1); } ...