设为首页 收藏本站
查看: 889|回复: 0

[经验分享] MySQL源码分析(1):源码结构及主要数据结构

[复制链接]

尚未签到

发表于 2015-12-22 11:21:47 | 显示全部楼层 |阅读模式
MySQL源码分析(1):源码结构及主要数据结构  




1. 源码结构(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:插件的目录,目前有一个全文搜索插件(只能用在myisam存储引擎)。

  

  • Pstack: 异步栈追踪工具。

  


  • Regex: 正则表达式工具。

  


  • Scripts: 提供脚本工具,如mysql_install_db等

  


  • Sql: 
mysql主要代码,数据库主程序mysqld所在的地方。大部分的系统流程都发生在这里。你还能看到sql_insert.cc, sql_update.cc, sql_select.cc,等等,分别实现了对应的SQL命令。后面我们还要经常提到这个目录下的文件。
大概有如下及部分:
   SQL解析器代码: sql_lex.cc, sql_yacc.yy, sql_yacc.cc, sql_parse.cc等,实现了对SQL语句的解析操作。
   "handler"代码: handle.cc, handler.h,定义了存储引擎的接口。
   "item"代码:item_func.cc, item_create.cc,定义了SQL解析后的各个部分。
   SQL语句执行代码: sql_update.cc, sql_insert.cc sql_select.cc, sql_show.cc, sql_load.cc,执行SQL对应的语句。当你要看"SELECT ..."的执行的时候,直接到sql_select.cc去看就OK了。
   辅助代码: net_serv.cc实现网络操作
   还有其他很多代码。
  

  

  • Sql-bench: 一些评测代码。
  

  • Sql-common: 存放部分服务器端和客户端都会用到的代码。
  

  • Storage:
  
  
这个目录包含了所谓的Mysql存储引擎 (storage engine)。存储引擎是数据库系统的核心,封装了数据库文件的操作,是数据库系统是否强大最重要的因素。Mysql实现了一个抽象接口层,叫做handler(sql/handler.h),其中定义了接口函数,比如:ha_open, ha_index_end, ha_create等等,存储引擎需要实现这些接口才能被系统使用。这个接口定义超级复杂,有900多行 :-(,不过我们暂时知道它是干什么的就好了,没必要深究每行代码。对于具体每种引擎的特点,我推荐大家去看mysql的在线文档: http://dev.mysql.com/doc/refman/5.1/en/storage-engines.html
应该能看到如下的目录:
* innobase, innodb的目录,当前最流行的存储引擎
* myisam, 最早的Mysql存储引擎,一直到innodb出现以前,使用最广的引擎。
* heap, 基于内存的存储引擎
* federated, 一个比较新的存储引擎
  * example, csv,这几个大家可以作为自己写存储引擎时的参考实现,比较容易读懂
  
  

  
  

  • Strings: string库。
  
  
  

  • Support-files: my.cnf示例配置文件。
  

  • Tests: 测试文件所在目录。
  

  • Unittest: 单元测试。
  

  • Vio:封装了virtual IO接口,主要是封装了各种协议的网络操作。
  


  • Win: 给windows平台提供的编译环境

  
  
  

  • Zip: zip库工具
  
  
  
  
2. 主要据结构

  

  • 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,>
  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_t my_write(File Filedes, const uchar *Buffer,>

  

  • 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; //全局系统变量

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-154714-1-1.html 上篇帖子: Mysql源代码分析系列(2): 主要调用流程 下篇帖子: mysqldump
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表