- 浏览: 183020 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
grzrt:
zkf55915 写道哥们怎么用啊
好久不用了,就是看帮助资 ...
淘宝MetaQ开源消息队列安装 -
zkf55915:
哥们怎么用啊
淘宝MetaQ开源消息队列安装 -
grzrt:
jinnianshilongnian 写道整这个了?
没有 看 ...
linux内核中链表的实现 -
jinnianshilongnian:
整这个了?
linux内核中链表的实现
经过多年的发展,mysql的主要模块已经稳定,基本不会有大的修改。本文将对MySQL的整体架构及重要目录进行讲述。
源码结构(MySQL-5.5.0-m2)
BUILD: 内含在各个平台、各种编译器下进行编译的脚本。如compile-pentium-debug表示在pentium架构上进行编译的脚本。
Client: 客户端工具,如mysql, mysqladmin之类。
Cmd-line-utils: readline, libedit工具。
Config: 给aclocal使用的配置文件。
Dbug: 提供一些调试用的宏定义。
Extra: 提供innochecksum,resolveip等额外的小工具。
Include: 包含的头文件
Libmysql: 库文件,生产libmysqlclient.so。
Libmysql_r: 线程安全的库文件,生成libmysqlclient_r.so。
Libservices: 5.5.0中新加的目录,实现了打印功能。
Man: 手册页。
Mysql-test: mysqld的测试工具一套。
Mysys: 为跨平台计,MySQL自己实现了一套常用的数据结构和算法,如string, hash等。
Netware: 在netware平台上进行编译时需要的工具和库。
Plugin: mysql以插件形式实现的部分功能。
Pstack: 异步栈追踪工具。
Regex: 正则表达式工具。
Scripts: 提供脚本工具,如mysql_install_db等
Sql: mysql主要代码,将会生成mysqld文件。
Sql-bench: 一些评测代码。
Sql-common: 存放部分服务器端和客户端都会用到的代码。
Storage: 存储引擎所在目录,如myisam, innodb, ndb等。
Strings: string库。
Support-files: my.cnf示例配置文件。
Tests: 测试文件所在目录。
Unittest: 单元测试。
Vio: virtual io系统,是对network io的封装。
Win: 给windows平台提供的编译环境。
Zip: zip库工具
主要数据结构
THD 线程描述符(sql/sql_class.h)
包含处理用户请求时需要的相关数据,每个连接会有一个线程来处理,在一些高层函数中,此数据结构常被当作第一个参数传递。
NET net; // 客户连接描述符
Protocol *protocol; // 当前的协议
Protocol_text protocol_text; // 普通协议
Protocol_binary protocol_binary; // 二进制协议
HASH user_vars; //用户变量的hash值
String packet; // 网络IO时所用的缓存
String convert_buffer; // 字符集转换所用的缓存
struct sockaddr_in remote; //客户端socket地址
THR_LOCK_INFO lock_info; // 当前线程的锁信息
THR_LOCK_OWNER main_lock_id; // 在旧版的查询中使用
THR_LOCK_OWNER *lock_id; //若非main_lock_id, 指向游标的lock_id
pthread_mutex_t LOCK_thd_data; //thd的mutex锁,保护THD数据(thd->query, thd->query_length)不会被其余线程访问到。
Statement_map stmt_map; //prepared statements和stored routines 会被重复利用
int insert(THD *thd, Statement *statement); // statement的hash容器
class Statement::
LEX_STRING name; /* prepared statements的名字 */
LEX *lex; //语法树描述符
bool set_db(const char *new_db, size_t new_db_len)
void set_query(char *query_arg, uint32 query_length_arg);
{
pthread_mutex_lock(&LOCK_thd_data);
set_query_inner(query_arg, query_length_arg);
pthread_mutex_unlock(&LOCK_thd_data);
}
NET 网络连接描述符(sql/mysql_com.h)
网络连接描述符,对内部数据包进行了封装,是client和server之间的通信协议。
Vio *vio; //底层的网络I/O socket描述符
unsigned char *buff,*buff_end,*write_pos,*read_pos; //缓存相关
unsigned long remain_in_buf,length, buf_length, where_b;
unsigned long max_packet,max_packet_size; //当前值;最大值
unsigned int pkt_nr,compress_pkt_nr; //当前(未)压缩包的顺序值
my_bool compress; //是否压缩
unsigned int write_timeout, read_timeout, retry_count; //最大等待时间
unsigned int *return_status; //thd中的服务器状态
unsigned char reading_or_writing;
/*1 代表读, 2 代表写, 0代表无状态 */
unsigned int last_errno; //返回给客户端的错误号
unsigned char error;
/*0:执行成功
1:在协议层有逻辑错误
2:系统调用或标准库出错
3:特例,表示缓存不能装下当前这么大的包
*/
TABLE 数据库表描述符(sql/table.h)
数据库表描述符,分成TABLE和TABLE_SHARE两部分。
handler *file; //指向这张表在storage engine中的handler的指针
THD *in_use; /* 使用这张表的thread号 */
Field **field; /* 指向数据域的指针*/
uchar *record[2]; /* 指向记录的指针*/
uchar *write_row_record; /* 在THD::write_row中用来做优化 */
uchar *insert_values; /* INSERT ... UPDATE语句用 */
/*
可用来直接获取表中数据而不用读取行的当前key的映射值
*/
key_map covering_keys;
key_map quick_keys, merge_keys;
key_map keys_in_use_for_query;
/* 可用以生成GROUP BY结果的key映射值 */
key_map keys_in_use_for_group_by;
/* 可用以生成ORDER BY 结果的key映射值 */
key_map keys_in_use_for_order_by;
KEY *key_info; /* 数据库中key的信息*/
HASH name_hash; //数据域名字的hash值
MEM_ROOT mem_root; //内存块
LEX_STRING db;
LEX_STRING table_name;
LEX_STRING table_cache_key;
enum db_type db_type //当前表的storage engine类型
enum row_type row_type //当前记录是定长还是变长
uint primary_key;
uint next_number_index; //自动增长key的值
bool is_view ;
bool crashed;
FIELD 字段描述符(sql/field.h)
域描述符,是各种字段的抽象基类。
uchar *ptr; // 记录中数据域的位置
uchar *null_ptr; // 记录 null_bit 位置的byte
TABLE *table; // 指向表的指针
TABLE *orig_table; // 指向原表的指针
const char **table_name, *field_name;
LEX_STRING comment;
/* 数据域是下列key的一部分 */
key_map key_start, part_of_key, part_of_key_not_clustered;
key_map part_of_sortkey;
/*各种数据域的类型*/
enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
BIT_FIELD, TIMESTAMP_OLD_FIELD, CAPITALIZE, BLOB_FIELD,
TIMESTAMP_DN_FIELD, TIMESTAMP_UN_FIELD, TIMESTAMP_DNUN_FIELD};
…..
virtual int store(const char *to, uint length,CHARSET_INFO *cs)=0;
inline String *val_str(String *str) { return val_str(str, str); }
Utility API Calls 各种API
各种核心的工具,例如内存分配,字符串操作或文件管理。标准C库中的函数只使用了很少一部分,C++中的函数基本没用。
void *my_malloc(size_t size, myf my_flags) //对malloc的封装
size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) //对write的封装
Preprocessor Macros 处理器宏
Mysql中使用了大量的C预编译,随编译参数的不同最终代码也不同。
#define max(a, b) ((a) > (b) ? (a) : (b)) //得出两数中的大者
do \
{ \
char compile_time_assert[(X) ? 1 : -1] \
__attribute__ ((unused)); \
} while(0)
使用gcc的attribute属性指导编译器行为
• Global variables 全局变量
• configuration settings
• server status information
• various data structures shared among threads
主要包括一些全局的设置,服务器信息和部分线程间共享的数据结构。
struct system_status_var global_status_var; //全局的状态信息
struct system_variables global_system_variables; //全局系统变量
主要调用流程
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();//主要处理函数,处理新的连接并创建新的线程处理之
监听接收链接
主要代码在sql/mysqld.cc中,精简后的代码如下:
THD *thd;
FD_SET(ip_sock,&clientFDs); //客户端socket
while (!abort_loop)
readFDs=clientFDs;
if (select((int) max_used_connection,&readFDs,0,0,0) error && net->vio != 0 &&
!(thd->killed == THD::KILL_CONNECTION))
{
if(do_command(thd)) //处理客户端发出的命令
break;
}
end_connection(thd);
}
预处理连接
thread_count++;//增加当前连接的线程
thread_scheduler.add_connection(thd);
for (;;) {
lex_start(thd);
login_connection(thd); // 认证
prepare_new_connection_state(thd); //初始化thd描述符
while(!net->error && net->vio != 0 &&
!(thd->killed == THD::KILL_CONNECTION))
{
if(do_command(thd)) //处理客户端发出的命令
break;
}
end_connection(thd);
}
处理
do_command在sql/sql_parse.cc中:读取客户端传递的命令并分发。
NET *net= &thd->net;
packet_length= my_net_read(net);
packet= (char*) net->read_pos;
command= (enum enum_server_command) (uchar) packet[0]; //从net结构中获取命令
dispatch_command(command, thd, packet+1, (uint) (packet_length-1));//分发命令
在dispatch_command函数中,根据命令的类型进行分发。
thd->command=command;
switch( command ) {
case COM_INIT_DB: ...;
case COM_TABLE_DUMP: ...;
case COM_CHANGE_USER: ...;
….
case COM_QUERY: //如果是查询语句
{
alloc_query(thd, packet, packet_length)//thd->set_query(query, packet_length);
mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
// 解析查询语句
….
}
在mysql_parse函数中,
lex_start(thd);
if (query_cache_send_result_to_client(thd, (char*) inBuf, length) sql_command
在mysql_execute_command中,根据命令类型,转到相应的执行函数。
switch (lex->sql_command) {
LEX *lex= thd->lex;
TABLE_LIST *all_tables;
case SQLCOM_SELECT:
check_table_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL, all_tables, UINT_MAX, FALSE); //检查用户权限
execute_sqlcom_select(thd, all_tables); //执行select命令
break;
case SQLCOM_INSERT:
{ res= insert_precheck(thd, all_tables) //rights
mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
lex->update_list, lex->value_list,
lex->duplicates, lex->ignore);
break;
在execute_sqlcom_select函数中,
res= open_and_lock_tables(thd, all_tables)//directly and indirectly
res= handle_select(thd, lex, result, 0);
handle_select在sql_select.cc中,调用mysql_select ,在mysql_select中,
join->prepare();//Prepare of whole select (including sub queries in future).
join->optimize();//global select optimisation.
join->exec();//
在mysql_insert函数中,
open_and_lock_tables(thd, table_list)
mysql_prepare_insert(); //prepare item in INSERT statment
while ((values= its++))
write_record(thd, table ,&info);//写入新的数据
在write_record函数中,
table->file->ha_write_row(table->record[0])
ha_write_row在Handler.cc中,只是一个接口
write_row(buf); //调用表存储所用的引擎
当客户端链接上mysql服务端时,系统为其分配一个链接描述符thd,用以描述客户端的所有信息,将作为参数在各个模块之间传递。一个典型的客户端查询在MySQL的主要模块之间的调用关系如下图所示:
当mysql启动完毕后,调用handle_connection_sockets等待客户端连接。当客户端连接上服务器时,服务处理函数将接受连接,会为其创建链接线程,并进行认证。如认证通过,每个连接线程将会被分配到一个线程描述符thd,可能是新创建的,也可能是从cached_thread线程池中复用的。该描述符包含了客户端输入的所有信息,如查询语句等。服务器端会层层解析命令,根据命令类型的不同,转到相应的sql执行函数,进而给传递给下层的存储引擎模块,处理磁盘上的数据库文件,最后将结果返回。执行完毕后thd将被加入cached_thread中。
参考资料:
High Performance MySQL
发表评论
-
MySQL中关于查询条件中的字符串空格问题
2013-02-20 19:17 7614假设当前mysql数据库中有个表:sysuser 有个字段 ... -
动态添加MYSQL从库,导出主库
2013-01-15 17:57 979http://dev.mysql.com/doc/refman ... -
MySQL主从失败 错误Got fatal error 1236解决方法
2013-01-09 16:45 1023由于主服务器异外重启, ... -
mysql 语句的调度优先级及改变
2012-12-07 16:47 1224MySQL的默认的调度策略可用总结如下: · 写入操作优 ... -
copy项目是容易出现的错误--webAppRootKey错误
2012-12-05 21:18 689Tomcat 发布多个项目时抛的webAppRootKey错误 ... -
redis主从的配置和使用
2012-11-23 14:24 1001redis主从的配置和使 ... -
Zookeeper的一致性协议:Zab
2012-11-04 16:14 1169Zookeeper使用了一种称为 ... -
MySQL水平分区表初体验总结
2012-09-21 15:22 1141本文总结个这段时间研究MySQL水平分区表总结,列举分区 ... -
小议同步IO :fsync与fdatasync
2012-09-13 20:23 686对于提供事务支持的 ... -
Linux修改MySql默认存储引擎为InnoDB
2012-09-13 18:25 1537一、关闭相关应用 二、停止mysql bin/m ... -
MySQL数据库的初始化mysql_install_db
2012-09-13 14:13 4650一、mysql_install_db说明 当MySQL的 ... -
四层和七层负载均衡的区别介绍
2012-09-12 11:46 806简单理解四层和七层负载均衡:①所谓四层就是基于IP+端口 ... -
LInux Tcp 延迟确认问题
2012-09-06 10:17 1358案例一:同事随手写个压力测试程序,其实现逻辑为:每秒钟先连续发 ... -
Nagle算法 TCP_NODELAY和TCP_CORK
2012-09-06 08:43 1171Nagle算法 根据创建者John Nagle命 ... -
socket中accept()函数的理解
2012-09-01 22:41 6762如果客户端有连接请 ... -
[mysql]不要再执着于thread_concurrency
2012-08-20 10:51 3328结论: thread_concurrency 在GNU ... -
【转】对mysql日志进行操作的总结包括 启用,过期自动删除 等
2012-08-19 17:25 8271. 以前我错误的认为mysql的日志可以恢复到任何时 ... -
mysql 主从复制1201错误
2012-08-19 15:59 901工作日志之-MySQL slave Replication E ... -
socket中的TIME_WAIT状态
2012-08-16 11:47 721TCP要保证在所有可能的 ... -
bloom filter 的Java 版
2012-07-26 21:50 850属于转贴:http://www.cnblo ...
相关推荐
2.4.2 1层数据流图 12 2.4.3 2层数据流图 13 第3章 系统概要设计 14 3.1系统设计思想 14 3.2系统总体设计 14 3.3系统功能模块设计 15 第4章 数据库设计 16 4.1概念模型设计 16 4.2数据表设计 17 第5章 系统详细设计...
之后是系统分析,具体完成了数据流分析和数据字典;系统设计阶段主要完成了功能模块的划分、数据库的设计和系统界面设计。该阶段对各个模块的功能进行了详细设计,形成了本系统的功能模块图,在此基础上选择了合适的...
资源名字:基于SSM+mysql的仓储系统出入库模块设计与实现(源码+设计文档+部署说明+视频演示).zip 资源内容:项目全套源码+完整文档 源码说明: 全部项目源码都是经过测试校正后百分百成功运行。 基于SSM+MySQL的...
毕业设计:基于SSM的mysql_高校心理测评设计与分析系统(源码 + 数据库 + 说明文档) 2 需求分析 3 2.1 功能需求 3 2.2 性能需求 4 2.3 用户需求 4 3 可行性分析 4 3.1经济可行性分析 5 3.2技术可行性分析 5 3.3...
2.3数据流分析 2 2.4在线教育平台开发流程 3 2.5用户登录流程 4 第3章 系统设计 5 3.1系统结构设计 5 3.2功能模块设计 5 3.3数据库设计 6 3.3.1数据库设计概述 6 3.3.2概念设计 6 3.3.3数据库表设计 7 第4章 系统...
数据统计:对用户学习数据进行统计和分析,以图表形式展示学习成果。 通过以上功能模块,智能学习平台系统为用户提供了一个全面、便捷的在线学习体验。同时,项目采用了分层架构和模块化设计,便于后期维护和扩展。
2.4.2 数据流的描述 15 2.4.3 外部实体的描述 16 第3章 系统设计 18 3.1 系统体系结构设计 18 3.2 系统子模块功能介绍 18 3.3 数据库设计 19 3.3.1 数据库概念设计——E-R模型 19 3.3.2 数据库逻辑设计——关系模型 ...
2.1.1数据流图 5 2.1.2系统的功能模块设计 7 2.1.3系统工作流程 9 2.2 数据库设计 12 2.2.1 E-R图 12 2.2.2 关系模式 12 2.2.3 数据表 13 第3章 系统实现 15 第4章 结束语 23 参考文献 24 附录: 主要源程序 26
3.5数据流分析 9 4 系统分析与设计 11 4.1系统功能结构框架 11 4.2数据库的概念结构设计 11 3.1.2数据库的逻辑结构设计 12 5 系统的实现 15 5.1 登录模块的实现 15 5.2 管理员管理界面 16 5.3教师添加管理页面 16 ...
系统登录功能二层数据流图 13 5.2.3.教师功能二层数据流图 13 5.2.4.学生功能二层数据流图 14 5.2.5.管理员功能二层数据流图 14 第六章 功能实现 15 6.1.系统登录模块 15 6.2.学生功能模块 15 6.2.1.学生登录...
4.2数据流图 6 4.3系统流程图 7 4.4数据库设计 7 4.4.1 数据库概要设计 7 4.4.2 数据表结构 8 第5章 系统的实现 10 5.1 首页界面展示 10 5.2 管理员管理界面 10 5.3 站内新闻管理界面 11 5.4 添加自习室界面 11 5.5 ...
2.4.2 数据流的描述 13 第3章 系统设计 15 3.1 系统体系结构设计 15 3.2 系统子模块功能介绍 15 3.3 数据库设计 16 3.3.1 数据库概念设计——E-R模型 16 3.3.2 数据库逻辑设计——关系模型 17 3.3.3 数据库选型 17 ...
毕业设计,基于Python+Django+MySql开发的二手车爬虫数据可视化分析,内含Python完整源代码,数据库脚本 基于Python的二手车爬虫...爬取的数据插入mysql数据库和分析数据读取mysql数据库表都是通过pymysql模块操作!