大家好,如果您还对大牛网站源码分享不太了解,没有关系,今天就由本站为大家分享大牛网站源码分享的知识,包括大牛软件论坛的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!
概述
今天主要从源码层面梳理mysql数据库目录结构、核心库以及启动过程中调用函数的顺序和作用。
1、MySQL目录结构
?build:内含有各个平台、各种编译器下进行编译的脚本。如compile-pentium-debug表示在pentium架构上进行调试编译的脚本。\n?client:客户端工具,如mysql,mysqladmin之类。\n?cmd-line-utils:readline,libedit工具。\n?config:给aclocal使用的配置文件。\n?dbug:提供一些调试用的宏定义。\n?Docs:MySQL在不同平台下的参考手册\n?extra:提供innochecksum,resolveip等额外的小工具。\n?include:包含的头文件\n?libmysql:库文件,生产libmysqlclient.so。\n?libmysql_r:线程安全的库文件,生成libmysqlclient_r.so。\n?libmysqld:嵌入式MySQLServer库.\n?libservices:5.5.0中新加的目录,实现了打印功能。\n?man:适合man命令查看的帮助文件。\n?mysql-test:mysqld的测试工具套件。\n?mysys:为实现跨平台,MySQL自己实现了一套常用的数据结构和算法,如string,hash等。还包含一些底层函数的跨平台封装,一般以my_开头。\n?netware:在netware平台上进行编译时需要的工具和库。\n?plugin:MySQL5.1开始支持一个插件式API接口,不需要重启mysqld即可动态载入插件,FullText就是一个例子。\n?pstack:GNU异步栈追踪工具。\n?regex:正则表达式实现(来自多伦多大学HenrySpencer大牛的源码)。\n?scripts:提供脚本工具,如mysql_install_db/mysqld_safe等。\n?server-tools:包含instance_manager子目录,负责实例的本地和远程管理。\n?sql:MySQLServer主要代码,将会生成mysqld文件。\n?sql-bench:一些基准测试代码代码,主要是Perl程序(虽然后缀是sh)。\n?sql-common:存放部分服务器端和客户端都会用到的代码,有些地方的同名文件是这里lin过去的。\n?storage:存储引擎所在目录。\n?strings:string库,包含很多字符串处理的函数。\n?support-files:my.cnf示例配置文件及编译所需的一些工具。\n?tests:测试文件所在目录。\n?unittest:单元测试文件。\n?vio:虚拟io系统,是对networkio的封装,把不同的协议封装成统一的IO函数。\n?win:在windows平台编译所需的文件和一些说明。\n?zlib:zlib算法库(GNU)\n
2、InnoDB目录结构
?btr:B+树的实现\n?buf:缓冲池的实现,包括LRU算法,Flush刷新算法等\n?dict:InnoDB内存数据字典的实现\n?dyn:InnoDB动态数组的实现\n?fil:InnoDB文件数据结构以及对于文件的一些操作\n?fsp:对InnoDB物理文件的管理,如页/区/段等(即FileSpace)\n?ha:哈希算法的实现\n?handler:继承与MySQL的handler,实现handlerAPI与Server交互\n?ibuf:插入缓冲(InsertBuffer)的实现\n?include:InnoDB所有头文件都放在这个目录,是查找结构定义的最佳地点\n?lock:InnoDB的锁实现及三种锁算法实现\n?log:日志缓冲(LogBuffer)和重做日志组(RedoLog)的实现\n?mem:辅助缓冲池(AdditionalMemoryPool)的实现,用来申请一些内部数据结构的内存\n?mtr:事务的底层实现(日志,缓冲)\n?os:封装一些对于操作系统的操作\n?page:页的实现,研究InnoDB文件结构,这个目录至关重要\n?pars:重载部分MySQL的SQLParser(有待商榷)\n?que:Querygraph,基本上没啥用\n?read:读取游标的实现\n?rem:行管理操作(比较操作,打印等)\n?row:对于各种类型行数据操作的实现\n?srv:InnoDB后台线程,启动服务,MasterThread,SQL队列等\n?sync:InnoDB互斥变量(Mutex)的实现,基本同步机制\n?thr:InnoDB封装的可移植线程库\n?trx:事务的实现\n?usr:Session管理\n?ut:各种通用小工具\n
3、核心类库
?THD:线程类\n?Item:Item类(查询条目,函数,WHERE,ORDER,GROUP,ON子句等)\n?TABLE:表描述符\n?TABEL_LIST:JOIN操作描述符\n?Field:列数据类型及属性定义\n?LEX:语法树\n?Protocol:通讯协议\n?NET:网络描述符\n?handler:存储引擎接口\n
4、核心函数库
4.1、内存操作:
?init_alloc_root:内存池初始化,生成内存池根(MEM_ROOT)\n?alloc_root:申请内存池内存,从mem_root制定的内存池申请内存块\n?free_root:释放内存池,通过MyFlags指定哪种内存可以被释放\n
4.2、文件操作:
?my_open:打开一个文件\n?my_close:关闭一个文件\n?my_b_flush_io_cache:讲数据从内存缓冲写到物理磁盘\n?end_io_cache:释放一个IO_CACHE对象\n
4.3、哈希操作:
?_hash_init:初始化HASH描述符\n?hash_search:搜索哈希表,调用hash_first\n?hash_first:返回哈希表中找到的第一个行指针,否则返回0\n
4.4、字符串操作:
?strappend:填充字符串\n?strmov:移动字符串到新地址\n
5、主要函数
主要函数和流程包括:
1.初始化系统变量和系统状态
2.初始化服务器的各个模块
以下为源码层面各个函数的基本说明:
源码分析\nmain\nmysqld_main(argc,argv)\n|pre_initialize_performance_schema();初始化performanceshcema相关内容\n|my_init()\n|load_defaults(MYSQL_CONFIG_NAME,load_default_groups,&argc,&argv)读取配置文件\n|init_pfs_instrument_array初始化performanceshcema相关内容\n|handle_early_options初始化部分变量,为mysqld初始化系统表等做准备\n|my_long_early_options变量设置,包括bootstrap、skip-grant-tables、help、verbose、version、initialize、initialize-insecure\n|init_sql_statement_names初始化命令,为后续status统计操作数量做准备\n|sys_var_init()初始化系统变量hash桶,将所有的系统变量插入到hash桶中(这里的变量为sys_vars.cc中定义的变量)\n|init_error_log初始化errorlog锁\n|mysql_audit_initialize初始化auditplugin锁,为后续初始化auditplugin做准备\n|query_logger.init();初始化generallog和slowlog的锁\n|init_common_variables()所有变量相关内容初始化,包括变量本身的值以及部分变量控制的特性\n|init_server_components()服务器各个模块的初始化,包括\n|init_server_auto_options()初始化UUID\n|if(gtid_state->read_gtid_executed_from_table()==-1)从gtid_execute表中读取gtid_execute\n|if(opt_bin_log)\n|gtid_state->get_executed_gtids()/gtid_state->get_lost_gtids()….如果开启了binlog,则初始化gtid相关信息\n|将gtid信息更新到mysql_bin_log中\n|将表中记录的gtid信息与binlog同步(包括purge,crashrecovery恢复等)\n|init_ssl()/network_init初始化ssl和网络\n|create_pid_file();创建pid文件\n|acl_init(opt_noacl)初始化用户名、密码等信息缓存,并将user表中的内容读取缓存\n|grant_init(opt_noacl)初始化权限缓存,将tables_priv等表中的权限信息读取缓存\n|servers_init(0);初始化mysql.servers表,并读入缓存\n|udf_init();初始化用户自定义函数\n|init_status_vars();初始化系统状态,systemstatus排序\n|init_slave()初始化slave相关的结构体\n如存在复制相关的信息,同时skip_slave_start未设置,则启动复制\n|execute_ddl_log_recovery执行ddl语句的crashrecovery\n|start_signal_handler();创建信号处理线程,处理信号SIGTERM/SIGQUIT/SIGHUP\n|if(opt_bootstrap)error=bootstrap(mysql_stdin);初始化数据目录、系统表\n|if(opt_init_file&&*opt_init_file)read_init_file(opt_init_file)从文件中初始化数据目录、系统表\n|mysqld_socket_acceptor->connection_event_loop();监听端口和sock文件,等待客户端连接\ninit_common_variables()所有变量相关的初始化\n|init_thread_environment初始化全局mutex和condition\n|mysql_init_variables设置部分全局变量的默认值\n|if(gethostname(glob_hostname,sizeof(glob_hostname))<0)……生成pid文件\n|设置默认存储引擎\n|if(add_status_vars(status_vars))将全局变量status_vars中的系统status存入all_status_vars中\n|get_options将设置的系统变量的值更新到系统变量中\n|set_default_auth_plugin设置默认的身份验证插件(通常为native_password)\n|set_server_version设置mysql版本的后缀(-embedded、-log、-debug…)\n|init_errmessage/init_client_errs初始化errormessage\n|item_create_init/item_init初始化所有的item类和函数(解析和后续执行使用)\n|初始化charset/collation\n|lex_init初始化解析sql使用的lex\n|初始化generallog和slowlog的日志名\nget_options将文件中、命令行中设置的参数,设置到系统参数中\n|将my_long_options存入all_options\n|将all_sys_vars存入all_options所有的系统变量均已存入all_options中\n|将{0,0,0,0,0,0,GET_NO_ARG,NO_ARG,0,0,0,0,0,0};存入all_option作为结束符\n|handle_options\n|if(Connection_handler_manager::init())初始化连接管理模块\n|if(Global_THD_manager::create_instance())初始化线程管理模块\ninit_server_components()\n|mdl_init初始化mdl锁\n|table_def_init/hostname_cache_init/my_timer_initialize\n|init_server_query_cachequerycache初始化\n|randominit随机数初始化\n|init_slave_list初始化从机hash桶\n|transaction_cache_init()事务缓存hash桶和锁初始化\n|delegates_initdelegates用于执行回调函数\n|if(opt_bin_log)如果变量中开启了binlog\n|生成binlog_index和binlog的文件名\n|if(opt_relay_logname)如果变量中开启了relaylog\n|生成relaylog_index和relaylog的文件名\n|if(ha_init_errors())将handler模块的错误信息注册到mysqld的my_error中\n|if(gtid_server_init())初始化gitd结构体\n|if(plugin_init(&remaining_argc,remaining_argv…初始化所有的插件(包括编译、配置、命令行加载的参数)\n|query_logger.set_handlers(log_output_options);初始化generallog/slowlog的日志处理模块\n|if(initialize_storage_engine(default_storage_engine,””….初始化默认的存储引擎\n|if(tc_log->open(opt_bin_log?opt_bin_logname:opt_tc_log_file))tc_log打开binlog,主要用于binlog和存储引擎的recovery使用,打开当前index中最后一个文件\n|if(ha_recover(0))recovery\n|if(mysql_bin_log.open_binlog(opt_bin_logname,0,mysql_bin_log打开binlog,生成新的binlog,在index文件中加入新的内容\n|mysql_bin_log.purge_logs_before_date(purge_time,true);如果开启了复制,同时开启了binlog定期删除时间,删除过期的binlog\n|init_max_user_conn(void)初始化连接hash桶\n|init_update_queries();初始化server_command_flags结构体,用于命令统计\n
入口函数在sql/main.cc文件中,里面只有一个函数,它又调用了mysqld_main,从这个函数开始到结束,就完成了mysqld的启动操作。
/*\nmain()formysqld.\nCallsmysqld_main()entrypointexportedbysqllibrary.\n*/\nexternintmysqld_main(intargc,char**argv);\nintmain(intargc,char**argv)\n{\nreturnmysqld_main(argc,argv);\n}\n
7、MySQL启动流程
主要代码在sql/mysqld.cc中,精简后的代码如下:
intmain(intargc,char**argv)//标准入口函数\nMY_INIT(argv[0]);//调用mysys/My_init.c->my_init(),初始化mysql内部的系统库\nlogger.init_base();//初始化日志功能\ninit_common_variables(MYSQL_CONFIG_NAME,argc,argv,load_default_groups)//调用load_defaults(conf_file_name,groups,&argc,&argv),读取配置信息\nuser_info=check_user(mysqld_user);//检测启动时的用户选项\nset_user(mysqld_user,user_info);//设置以该用户运行\ninit_server_components();//初始化内部的一些组件,如table_cache,query_cache等。\nnetwork_init();//初始化网络模块,创建socket监听\nstart_signal_handler();//创建pid文件\nmysql_rm_tmp_tables()||acl_init(opt_noacl)//删除tmp_table并初始化数据库级别的权限。\ninit_status_vars();//初始化mysql中的status变量\nstart_handle_manager();//创建manager线程\nhandle_connections_sockets();//主要处理函数,处理新的连接并创建新的线程处理\n
觉得有用的朋友多帮忙转发哦!后面会分享更多devops和DBA方面的内容,感兴趣的朋友可以关注下~
好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!
