从源码角度看mysql数据库目录结构、核心库以及数据库启动过程
cac55 2024-10-19 02:54 13 浏览 0 评论
概述
今天主要从源码层面梳理mysql数据库目录结构、核心库以及启动过程中调用函数的顺序和作用。
1、MySQL目录结构
?build: 内含有各个平台、各种编译器下进行编译的脚本。如compile-pentium-debug表示在pentium架构上进行调试编译的脚本。 ?client: 客户端工具,如mysql,mysqladmin之类。 ?cmd-line-utils: readline,libedit工具。 ?config: 给aclocal使用的配置文件。 ?dbug: 提供一些调试用的宏定义。 ?Docs: MySQL在不同平台下的参考手册 ?extra: 提供innochecksum,resolveip等额外的小工具。 ?include: 包含的头文件 ?libmysql: 库文件,生产libmysqlclient.so。 ?libmysql_r: 线程安全的库文件,生成libmysqlclient_r.so。 ?libmysqld: 嵌入式MySQL Server库. ?libservices: 5.5.0中新加的目录,实现了打印功能。 ?man: 适合man命令查看的帮助文件。 ?mysql-test: mysqld的测试工具套件。 ?mysys: 为实现跨平台,MySQL自己实现了一套常用的数据结构和算法,如string, hash等。还包含一些底层函数的跨平台封装,一般以my_开头。 ?netware: 在netware平台上进行编译时需要的工具和库。 ?plugin: MySQL 5.1开始支持一个插件式API接口,不需要重启mysqld即可动态载入插件,FullText就是一个例子。 ?pstack: GNU异步栈追踪工具。 ?regex: 正则表达式实现(来自多伦多大学Henry Spencer大牛的源码)。 ?scripts: 提供脚本工具,如mysql_install_db/mysqld_safe等。 ?server-tools: 包含instance_manager子目录,负责实例的本地和远程管理。 ?sql: MySQL Server主要代码,将会生成mysqld文件。 ?sql-bench: 一些基准测试代码代码,主要是Perl程序(虽然后缀是sh)。 ?sql-common: 存放部分服务器端和客户端都会用到的代码,有些地方的同名文件是这里lin过去的。 ?storage: 存储引擎所在目录。 ?strings: string库,包含很多字符串处理的函数。 ?support-files: my.cnf示例配置文件及编译所需的一些工具。 ?tests: 测试文件所在目录。 ?unittest: 单元测试文件。 ?vio: 虚拟io系统,是对network io的封装,把不同的协议封装成统一的IO函数。 ?win: 在windows平台编译所需的文件和一些说明。 ?zlib: zlib算法库(GNU)
2、InnoDB目录结构
?btr: B+树的实现 ?buf: 缓冲池的实现,包括LRU算法,Flush刷新算法等 ?dict: InnoDB内存数据字典的实现 ?dyn: InnoDB动态数组的实现 ?fil: InnoDB文件数据结构以及对于文件的一些操作 ?fsp: 对InnoDB物理文件的管理,如页/区/段等(即File Space) ?ha: 哈希算法的实现 ?handler: 继承与MySQL的handler,实现handler API与Server交互 ?ibuf: 插入缓冲(Insert Buffer)的实现 ?include: InnoDB所有头文件都放在这个目录,是查找结构定义的最佳地点 ?lock: InnoDB的锁实现及三种锁算法实现 ?log: 日志缓冲(Log Buffer)和重做日志组(Redo Log)的实现 ?mem: 辅助缓冲池(Additional Memory Pool)的实现,用来申请一些内部数据结构的内存 ?mtr: 事务的底层实现(日志,缓冲) ?os: 封装一些对于操作系统的操作 ?page: 页的实现,研究InnoDB文件结构,这个目录至关重要 ?pars: 重载部分MySQL的SQL Parser(有待商榷) ?que: Query graph,基本上没啥用 ?read: 读取游标的实现 ?rem: 行管理操作(比较操作,打印等) ?row: 对于各种类型行数据操作的实现 ?srv: InnoDB后台线程,启动服务,Master Thread,SQL队列等 ?sync: InnoDB互斥变量(Mutex)的实现,基本同步机制 ?thr: InnoDB封装的可移植线程库 ?trx: 事务的实现 ?usr: Session管理 ?ut: 各种通用小工具
3、核心类库
?THD: 线程类 ?Item: Item类(查询条目,函数,WHERE,ORDER,GROUP,ON子句等) ?TABLE: 表描述符 ?TABEL_LIST: JOIN操作描述符 ?Field: 列数据类型及属性定义 ?LEX: 语法树 ?Protocol: 通讯协议 ?NET: 网络描述符 ?handler: 存储引擎接口
4、核心函数库
4.1、内存操作:
?init_alloc_root: 内存池初始化,生成内存池根(MEM_ROOT) ?alloc_root: 申请内存池内存,从mem_root制定的内存池申请内存块 ?free_root: 释放内存池,通过MyFlags指定哪种内存可以被释放
4.2、文件操作:
?my_open: 打开一个文件 ?my_close: 关闭一个文件 ?my_b_flush_io_cache: 讲数据从内存缓冲写到物理磁盘 ?end_io_cache: 释放一个IO_CACHE对象
4.3、哈希操作:
?_hash_init: 初始化HASH描述符 ?hash_search: 搜索哈希表,调用hash_first ?hash_first: 返回哈希表中找到的第一个行指针,否则返回0
4.4、字符串操作:
?strappend:填充字符串 ?strmov: 移动字符串到新地址
5、主要函数
主要函数和流程包括:
1. 初始化系统变量和系统状态
2. 初始化服务器的各个模块
以下为源码层面各个函数的基本说明:
源码分析 main mysqld_main(argc, argv) | pre_initialize_performance_schema(); 初始化performance shcema相关内容 | my_init() | load_defaults(MYSQL_CONFIG_NAME, load_default_groups, &argc, &argv) 读取配置文件 | init_pfs_instrument_array 初始化performance shcema相关内容 | handle_early_options 初始化部分变量,为mysqld初始化系统表等做准备 | my_long_early_options变量设置,包括bootstrap、skip-grant-tables、help、verbose、version、initialize、initialize-insecure | init_sql_statement_names 初始化命令,为后续status统计操作数量做准备 | sys_var_init() 初始化系统变量hash桶,将所有的系统变量插入到hash桶中(这里的变量为sys_vars.cc中定义的变量) | init_error_log 初始化error log 锁 | mysql_audit_initialize 初始化audit plugin锁,为后续初始化audit plugin做准备 | query_logger.init(); 初始化general log和slow log的锁 | init_common_variables() 所有变量相关内容初始化,包括变量本身的值以及部分变量控制的特性 | init_server_components() 服务器各个模块的初始化,包括 | init_server_auto_options() 初始化UUID | if (gtid_state->read_gtid_executed_from_table() == -1) 从gtid_execute表中读取gtid_execute | if (opt_bin_log) | gtid_state->get_executed_gtids()/gtid_state->get_lost_gtids() .... 如果开启了binlog,则初始化gtid相关信息 | 将gtid 信息更新到 mysql_bin_log中 | 将表中记录的gtid信息与binlog同步(包括purge,crash recovery恢复等) | init_ssl()/network_init 初始化ssl和网络 | create_pid_file(); 创建pid文件 | acl_init(opt_noacl) 初始化用户名、密码等信息缓存,并将user表中的内容读取缓存 | grant_init(opt_noacl) 初始化权限缓存,将tables_priv等表中的权限信息读取缓存 | servers_init(0); 初始化mysql.servers表,并读入缓存 | udf_init(); 初始化用户自定义函数 | init_status_vars(); 初始化系统状态,system status排序 | init_slave() 初始化slave相关的结构体 如存在复制相关的信息,同时skip_slave_start未设置,则启动复制 | execute_ddl_log_recovery 执行ddl语句的crash recovery | start_signal_handler(); 创建信号处理线程,处理信号SIGTERM/SIGQUIT/SIGHUP | if (opt_bootstrap) error= bootstrap(mysql_stdin); 初始化数据目录、系统表 | if (opt_init_file && *opt_init_file) read_init_file(opt_init_file) 从文件中初始化数据目录、系统表 | mysqld_socket_acceptor->connection_event_loop(); 监听端口和sock文件,等待客户端连接 init_common_variables() 所有变量相关的初始化 | init_thread_environment 初始化全局mutex和condition | mysql_init_variables 设置部分全局变量的默认值 | if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0) ...... 生成pid文件 | 设置默认存储引擎 | if (add_status_vars(status_vars)) 将全局变量status_vars中的系统 status存入all_status_vars中 | get_options 将设置的系统变量的值更新到系统变量中 | set_default_auth_plugin 设置默认的身份验证插件(通常为native_password) | set_server_version 设置mysql版本的后缀(-embedded、-log、-debug...) | init_errmessage/init_client_errs 初始化error message | item_create_init/item_init 初始化所有的item类和函数(解析和后续执行使用) | 初始化 charset/collation | lex_init 初始化解析sql使用的lex | 初始化general log 和 slow log的日志名 get_options 将文件中、命令行中设置的参数,设置到系统参数中 |将my_long_options存入all_options |将all_sys_vars存入all_options 所有的系统变量均已存入all_options中 |将 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}; 存入all_option 作为结束符 |handle_options |if (Connection_handler_manager::init()) 初始化连接管理模块 |if (Global_THD_manager::create_instance()) 初始化线程管理模块 init_server_components() | mdl_init 初始化mdl锁 | table_def_init/hostname_cache_init/my_timer_initialize | init_server_query_cache query cache初始化 | randominit 随机数初始化 | init_slave_list 初始化从机hash桶 | transaction_cache_init() 事务缓存hash桶和锁初始化 | delegates_init delegates用于执行回调函数 | if (opt_bin_log) 如果变量中开启了binlog | 生成binlog_index 和 binlog的文件名 | if (opt_relay_logname) 如果变量中开启了relaylog | 生成relaylog_index 和 relay log的文件名 | if (ha_init_errors()) 将handler模块的错误信息注册到mysqld的my_error中 | if (gtid_server_init()) 初始化gitd结构体 | if (plugin_init(&remaining_argc, remaining_argv ... 初始化所有的插件(包括编译、配置、命令行加载的参数) | query_logger.set_handlers(log_output_options); 初始化general log/slow log的日志处理模块 | if (initialize_storage_engine(default_storage_engine, "".... 初始化默认的存储引擎 | if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file)) tc_log打开binlog,主要用于binlog和存储引擎的recovery使用,打开当前index中最后一个文件 | if (ha_recover(0)) recovery | if (mysql_bin_log.open_binlog(opt_bin_logname, 0, mysql_bin_log打开binlog,生成新的binlog,在index文件中加入新的内容 | mysql_bin_log.purge_logs_before_date(purge_time, true); 如果开启了复制,同时开启了binlog定期删除时间,删除过期的binlog | init_max_user_conn(void) 初始化连接hash桶 | init_update_queries(); 初始化server_command_flags结构体,用于命令统计
入口函数在sql/main.cc文件中,里面只有一个函数,它又调用了mysqld_main,从这个函数开始到结束,就完成了mysqld的启动操作。
/* main() for mysqld. Calls mysqld_main() entry point exported by sql library. */ extern int mysqld_main(int argc, char **argv); int main(int argc, char **argv) { return mysqld_main(argc, argv); }
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();//主要处理函数,处理新的连接并创建新的线程处理
觉得有用的朋友多帮忙转发哦!后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~
相关推荐
- 为什么要对彗星“深度撞击”(比特彗星中文破解版)
-
在太阳系中,被人类探测器造访的彗星数量与行星数量差不多。其中绝大多数探测器都是从彗星附近飞过采集数据。但2005年“深度撞击”探测器则采取了主动出击的策略。它释放出的撞击体以10千米/秒的速度撞...
- 准妈妈备产清单:看看凯特王妃待产包里都有啥
-
来源:新华网英国威廉王子和凯特王妃即将迎来他们的第三个孩子。据悉,同生乔治王子和夏洛特公主时一样,此次凯特仍然选择在伦敦圣玛丽医院生产。那么,凯特的待产包里有些什么呢?匿名消息源向英国《OK!》杂志透...
- 系统小技巧:正确处理软件放行与禁用的矛盾
-
有时,我们讨厌一些程序运行,但它们偏偏会自动弹出,我们希望禁止其运行。而还有的时候,因为某种原因使用了比较复杂的“软件限制策略”,造成某些软件无法运行,这时我们希望将其解禁。虽然我们可以用修改注册表的...
- 老网民的青春:盘点那些消失在互联网中的软件,你用过哪款?
-
一则ICQ即将关闭的消息,唤醒了很多70后80后尘封的记忆。ICQ可以说是即时通讯软件的鼻祖,它诞生于1996年,由以色列公司Mirabilis推出,ICQ是Iseekyou的简写,中文释义为“我...
- Windows Vista 动态桌面的设置(windows10动态桌面)
-
一、VMwareWorkstation15(16的版本能安装但是不能实现动态桌面)安装WindowsVistaEnterprise,15下安装及设置完成后,在16下可以正常显示,虚拟机下安装...
- Hexoskin智能T恤 穿在身上的运动追踪器
-
来源:MSN理财综合|2016-01-0615:14:42[摘要]Hexoskin使用方便,续航时间超长。它能准确追踪运动数据,可以满足专业运动员以及热爱健身的人,官网售价399美元。其实不用多说什...
- 你了解这些互联网的名词吗?(互联网的别称有哪些)
-
要想成为互联网的菜鸟,可以先了解一下互联网的一些基础名词。现在就一起来来看看吧,记住了,可以应急用哦!PV:即页面浏览量,或点击量(用户每次刷新即被计算一次)UV:独立访客(UniqueVisi...
- 不要成为无用的大人——写给三十岁前的你
-
我不习惯写励志故事,看到鸡汤绕道而行,原因是任何人选择入世生活,就并不值得安慰,以及不要期待享受特权,也没有你必须不得承受的麻烦。金牛座的世界里遭遇一切苦都是应该的,一切得到则需要努力得到,而且要认真...
- 尼康宣布正研发专业级FX格式数码单反相机D5
-
尼康宣布正在研发专业级FX格式数码单反相机D5。作为D4s的后续机型,D5机型的命名源于此款产品代表了尼康数码单反相机的第5代专业级机型。D4s于2014年2月发布,作为专业级数码单反相机,一经推出,...
- 配置管理流程(配置管理流程属于)
-
资料来源:https://www.cnblogs.com/wayne-ivan/articles/525818.html1 概要1.1 内容规范配置管理活动,确保配置项正确地唯一标识并易于存取,保证基...
- 小密圈-重新定义你的朋友圈(小密圈开放了)
-
微信在我们的生活中已经被使用的非常广泛了,除了聊天、视频之外,用的最多的就是朋友圈。在朋友圈里分享自己每天的所感所悟,家长里短本来是一件很开心的事,但是最近的一条新闻引起了人们的关注。某白领因为不愿意...
- 十招教你找到海量PPT模板(怎么找ppt模板资源)
-
配图设计:@乌素淖尔我每天都能遇到这种求助问题,不堪重负。问:急求XXXPPT模版?无耻的来求PPT模版,我是在一家互联网公司工作的小员工,领导安排说年初要用PPT做一份工作计划报告,主要是想说一下今...
- 安卓系统手机文件夹及其文件详细解析
-
打开Android文件管理器,会发现里面数十个英文名称命名的文件夹罗列其中,很多功能我们可以从其名字上略有所知,内部大批量的文件却让我们有些一头雾水。这些文件是什么呢?有什么用?我们能不能删?这些都是...
- 我为什么不喜欢微信(有没有人不喜欢聊微信)
-
这个问题是我在知乎的一个回答,原始问题是“什么样的用户不喜欢微信”?出于数据备份的原因,将其复制保留一份到这里,以防丢失。以下是原回答内容:我是做技术出身的,我非常不喜欢微信,同样也不喜欢QQ,但是为...
- 花了一周时间,整理出推荐频率最高的14款办公必备软件
-
澄清!猫猫最近没有偷懒!猫猫去干大事儿了!随着猫猫推荐的软件越来越多,大家是不是也苦恼每次想找一类软件,还得去一篇一篇翻历史文章,其实我也很苦恼这个问题。于是!猫猫上周搭建了一个“猫猫软件中心”,这里...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 如何绘制折线图 (52)
- javaabstract (48)
- 新浪微博头像 (53)
- grub4dos (66)
- s扫描器 (51)
- httpfile dll (48)
- ps实例教程 (55)
- taskmgr (51)
- s spline (61)
- vnc远程控制 (47)
- 数据丢失 (47)
- wbem (57)
- flac文件 (72)
- 网页制作基础教程 (53)
- 镜像文件刻录 (61)
- ug5 0软件免费下载 (78)
- debian下载 (53)
- ubuntu10 04 (60)
- web qq登录 (59)
- 笔记本变成无线路由 (52)
- flash player 11 4 (50)
- 右键菜单清理 (78)
- cuteftp 注册码 (57)
- ospf协议 (53)
- ms17 010 下载 (60)