本文是基于Percona-Server-5.1.54源码进行学习的。参考了《深入理解Mysql核心技术》 。
MYSQL服务器主要模块:
l 服务器初始化模块
l 连接管理器
l 线程管理器
l 连接线程
l 用户验证模块
l 访问控制模块
l 解析器
l 命令调度器
l 查询高速缓存模块
l 优化器
l 表管理器
l 表修改模块
l 表维护模块
l 状态报告模块
l 抽象存储引擎接口
l 存储引擎实现(MyISAM、InnoDB)
l 日志记录模块
l 主复制服务器模块
l 从复制服务器模块
l 客户端/服务器协议API
l 低层次网络I/O API
l 核心API
模块间的关系非常清晰:服务器启动时先进行初始化操作,连接管理器侦听客户端的连接
,当有客户请求连接的时候,线程管理器会为之创建一个连接线程,同时判断该用户是否
有效,连接线程用来处理客户端后面相应的请求,当客户的一个请求(命令、查询)到来
的时候,经过命令调度器进行调度如果是命令的话,则直接执行,否则通过解析器进行解
析,判断是否是在查询高速缓存中,如果是的话直接返回,否则再解析,在解析器中生成
一棵解析树,根据命令类型选择各个模块分支,这些分支包括:表管理器模块、 表修改模
块、 表维护模块、 状态报告模块。这些模块就包含了我们平时进行的如select,create DB
,create table,update,delete,drop,show等等。其中在执行select(调用handle_select函
数)的时候会调用优化器对查询进行优化,然后再执行。而另外的表及库更新操作则会调用
存储引擎进行实际数据的存储,索引的更新等,当然这些操作都伴随着访问控制,如是否
具有该操作的权限。
----------------------------------------------------------------------------------------------------------------
服务器初始化模块:
当通过命令行启动服务器时,初始化模块接过控制权。它解析配置文件和命令行参数、分
配全局存储缓冲区、初始化全局变量和结构、加载访问控制表,以及执行大量其它的初始
化任务。一旦完成初始化任务,初始化模块就将控制权交给连接管理器,连接管理器开始
侦听来自回路中的客户端的连接。
./sql/mysqld.cc/main()
{
MY_INIT(argv[0]); // init my_sys library & pthreads: ./mysys/My_init.c/my_init()
//Initialize thread environment、Initialize all MySQL global variables to default values、load configure files
init_common_variables();
init_server_components();
network_init();
grant_init();
servers_init();
init_status_vars();
init_slave();
execute_ddl_log_recovery();
create_shutdown_thread();
start_handle_manager();
handle_connections_sockets();
}
----------------------------------------------------------------------------------------------------------------------
连接管理器:
当客户端连接到数据库服务器时,连接管理器执行大量低层次网络协议任务,然后将控
制权传递给线程管理器。
./sql/mysqld.cc/handle_connections_sockets()
{
select((int) max_used_connection,&readFDs,0,0,0);
accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),&length);
vio_new();
my_net_init();
create_new_thread(thd);
}
----------------------------------------------------------------------------------------------------------------------------
线程管理器:
当线程管理器接到连接管理器传来一个请求时,创建一个连接线程。
.sql/mysqld.cc/create_new_thread()
{
thread_scheduler.add_connection(thd);
}
-------------------------------------------------------------------------------------------------------------------------------
连接线程:
当线程管理器创建了一个连接线程后,它将处理已建立连接的客户端请求。它首先调用
用户验证模块,连接用户的证书经过验证后,初始化处理请求查询的线程结构,处理客
户的请求。连接线程由下面两个函数创建:
./sql/mysqld.cc/handle_connection_in_main_thread()
./sql/mysqld.cc/create_thread_to_handle_connection()
连接线程函数:
./sql/sql_connect.cc/handle_one_connection()
{
lex_start();
login_conection();
prepare_new_connection_state();
do_command();
}
---------------------------------------------------------------------------------------------------------------------
用户验证模块:
用户验证模块验证所连接的用户,并对包含该用户层权限信息的结构和变量进行初始化。
该模块由./sql/sql_connect.cc/login_connection()进入check_connection()。所包含的其它函数包括:
./sql/sql_acl.cc/ acl_check_host()、./sql/password.cc/create_random_string()、
./sql/sql_acl.cc/acl_getroot()等。
./sql/sql_connection.cc/check_connection()
{
acl_check_host();
create_random_string();
check_user();
}
---------------------------------------------------------------------------------------------------------------------
命令调度器:
连接线程将请求数据传递给命令调度器do_command()。MYSQL有两种客户请求:查询和
命令。查询是任何必须通过解析器的请求,而命令则是无需调用解析器即可执行的请求。
./sql/sql_parse.cc/do_command()
{
dispatch_command();-------à|switch(command)
|case 命令:
| mysql_change_db();
| register_slave ();
| mysql_table_dump ();
| check_user ();
| mysqld_stmt_execute ();
| mysqld_stmt_fetch ();
| ERROR: my_message();
| ……
| break;
|case: 查询
| mysql_parse();
| net_end_statement();
| query_cache_end_of_result ();
| close_thread_tables ();
| log_slow_statement ();
| …….
| break;
}
-----------------------------------------------------------------------------------------------------------------------
其它内容见《Mysql学习笔记:Mysql服务器体系结构(二)》