【MySQL源码】01 MySQL源码总述
目录1. 版本关系2. MySQL MariaDB 安装2.1. MariaDB安装2.1.1. 源码编译安装2.2. docker运行2.3. 安装MySQL3. 文件目录 & 类 概述3.1. 文件3.1.1. 头文件3.2. 类4. MySQL语句解析器 – lex + yacc4.1. 概述4.2. Lex 词法解析器4.3. yacc 语法解析器5. MySQL语句 成员分析5.
目录
1. 版本关系
- MariaDB与MySQL的版本对应关系 
参考:
2. MySQL MariaDB 安装
2.1. MariaDB安装
2.1.1. 源码编译安装
使用源码编译后进行安装;
参考:
2.2. docker运行
- 
  安装高版本MariaDB - 配置MariaDB的yum源设置;
- 使用yum进行安装或升级;
 
- 
  mariadb设置登录密码: MariaDB [(none)]> USE mysql; MariaDB [(none)]> UPDATE user SET password=PASSWORD('YourPasswordHere') WHERE User='root' AND Host = 'localhost'; MariaDB [(none)]> FLUSH PRIVILEGES;
参考:
      1. centos7.5下yum 安装mariadb10.3详解
2.3. 安装MySQL
- 问题: 
  - mysql 数据持久化问题
    # 获取镜像 docker search mysql docker pull centos/mysql-57-centos7:5.7 # 运行容器, 需要做数据挂载 //安装启动mysql,需要配置密码; ## 官方命令 docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag ## 实践 docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 ## 连接 mysql -uroot -p'123456' -P3310 -h192.168.0.120
 
- mysql 数据持久化问题
    
参考:
3. 文件目录 & 类 概述
3.1. 文件
参考:
3.1.1. 头文件
- 
  item.h: 
 总的对象定义类,定义了’Item’类作为总的对象类,此后,本文件中定义了许多子类,来丰富和发展MySQL可以处理的对象。但此类继承自’Parse_tree_node’类,使得对象和词法语法解析关联起来,这个不细述。
- 
  item_cmpfunc.h: 
 定义了’Item_bool_func’类,继承自’Item_int_func’类,而Item_int_func继承自Item_func,Item_func类继承自Item类。'Item_bool_func’类主要用于支持比较操作,如等于、大于、小于、IN、BETWEEN、是否为NULL等。
- 
  item_create.h: 
 用户自定义函数的创建接口。
- 
  item_func.h: 
 定义了 Item_func类,继承自Item类,用以支持各种函数操作。如求绝对值、求长度、取余等等。本文件中也定义了许多子类,来丰富和发展MySQL可以处理的对象。
- 
  item_geofunc.h: 
 空间对象处理相关函数。
- 
  item_inetfunc.h: 
 定义IPv4、IP6的处理。
- 
  item_sum.h: 
 定义聚集函数的处理。包括MIN和MAX,但通常这2函数个是利用索引进行优化的。
3.2. 类
4. MySQL语句解析器 – lex + yacc
4.1. 概述
- 
  解析过程  
- 
  解析器: - mysql是使用了开始的bison(即yacc的开源版)作为sql语法解析器;
- 在mysql源码中,解析sql在sql_yacc.yy中实现,而sql_yacc.yy 借助 bison 来转换为c文件。
 
- 
  SQL解析相关文件及关联 - 
    SQL词法解析文件: 
 sql/sql_lex.h、sql/lex_token.h、sql/lex.h、sql/lex_symbol.h
 sql/gen_lex_token.cc、sql/sql_lex.cc
- 
    SQL语法解析文件: 
 sql/sql_yacc.yy、sql/sql_yacc.cc、sql/sql_yacc.h
- 
    SQL语句的hint语法解析文件: 
 sql/sql_hints.yy、sql/sql_hints.yy.cc
 
- 
    
4.2. Lex 词法解析器
4.3. yacc 语法解析器
yacc
  bison
参考:
- MySQL内核源码解读-SQL解析一 //Bison
- 从Mysql源代码角度分析一句简单sql的查询过程 //重要
5. MySQL语句 成员分析
5.1. 语句解析过程
参考:
下文只对常用的select(SQLCOM_SELECT), update(SQLCOM_UPDATE), insert(SQLCOM_INSERT), delete(SQLCOM_DELETE)做一下介绍。
- 
  5.1 Select语句 
 对select类型的语句解析后,将结果存放在SELECT_LEX类中
 其中:
 选择域存放在SELECT_LEX::item_list中,类型为LIST
 where域存放在SELECT_LEX::wheret中,类型为Item*
 having域存放在SELECT_LEX::having中,类型为Item*
 order域存放在SELECT_LEX::order_list中,实际类型为ORDER*
 group域存放在SELECT_LEX::group_list中,实际类型为ORDER*
 limit域存放在SELECT_LEX::select_limit中,unsigned long
 table名字域存放在SELECT_LEX::table_list中,实际类型为TABLE_LIST*
 (其中选择域的结构请见上文中的4(1),where域和having域的解构请见上文中的4(2), 其他几个域的解构类似于链表)
- 
  5.2 Update语句 
 对update类型的语句解析后,将结果存放在SELECT_LEX类和LEX类中
 其中:
 更新域存放在SELECT_LEX::item_list中,类型为LIST
 值域存放在LEX::value_list中,类型为LIST
 where域存放在SELECT_LEX::wheret中,类型为Item*
 table名字域存放在SELECT_LEX::table_list中,实际类型为TABLE_LIST*
 (其中更新域和值域的结构请见上文中的4(1),where域的解构请见上文中的4(2), table名字域的解构类似于链表)
- 
  5.3 Insert语句 
 对insert类型的语句解析后,将结果存放在SELECT_LEX类和LEX类中
 其中:
 插入域存放在LEX::item_list中,类型为LIST
 值域存放在LEX::many_values中,类型为LIST<LIST>
 table名字域存放在SELECT_LEX::table_list中,实际类型为TABLE_LIST*
 (其中插入域的结构请见上文中的4(1), 值域可以含有多个LIST, table名字域的解构类似于链表)
- 
  5.4 Delete语句 
 对delete类型的语句解析后,将结果存放在SELECT_LEX类中
 其中:
 where域存放在SELECT_LEX::wheret中,类型为Item*
 limit域存放在SELECT_LEX::select_limit中,unsigned long
 table名字域存放在SELECT_LEX::table_list中,实际类型为TABLE_LIST*
 (其中选择域的结构请见上文中的4(1),where域和having域的解构请见上文中的4(2), 其他几个域的解构类似于链表)
5.2. select 语句
参考:
5.2.1. select 语句中子查询处理逻辑的分析
- 
  主要数据结构 & 相互关系 - 
    select 结构 - MySQL解析器中负责分析和存储一个select语句信息的数据结构是st_select_lex类(MySQL中同时将该类宏定义为 SELECT_LEX);
- 同时负责分析和存储union关系的数据结构是st_select_lex_unit类(MySQL中同时将该类宏定义为SELECT_LEX_UNIT);
- 而这两个类都继承于 st_select_lex_node类。
 
- MySQL解析器中负责分析和存储一个
- 
    SELECT_LEX类- 对于SELECT_LEX类,它主要是存储一个select语句中select子句的返回列信息,from子句中的表信息,order by,group by子句的列信息等。
- 对于本文所关心的问题,SELECT_LEX类使用继承于st_select_lex_node类的 next指针存储和该select语句进行union操作的其他select语句对应的 SELECT_LEX的地址,通过该指针串成union链表;
 
 
- 
    
- 
  具体存储方式 - 语句 & 存储结构
    //见:参考1 # 语句 (SELECT ...) UNION (SELECT ... (SELECT...)...(SELECT...UNION...SELECT)) 1 2 3 4 5 6 7 # 数据结构 ------------------------------------------------------------------------ level 1 SELECT_LEX_UNIT(2) | +---------------+ |(UNIT->slave) | SELECT_LEX(1) SELECT_LEX(3) ---SELECT_LEX(1)->next | --------------- | ------------------------------------------------------ | level 2 +-------------------+ | | SELECT_LEX_UNIT(4) SELECT_LEX_UNIT(6) | | | +--------------+ | | | SELECT_LEX(4) SELECT_LEX(5) SELECT_LEX(7) ------------------------------------------------------------------------
- 解析: 
    - SELECT_LEX_UNIT负责管理处于同一级的进行 union操作 的- 数个select子句对应的SELECT_LEX;
- 指针: 
      - SELECT_LEX_UNIT 通过继承于st_select_lex_node类 的 slave指针 存储属于这一级的进行union操作的 第一个SELECT_LEX;
- 这一级别其他参与union操作的SELECT_LEX,可以通过 next指针 串成的链表依次找到。
 
- SELECT_LEX_UNIT 通过继承于st_select_lex_node类 的 slave指针 存储属于这一级的进行union操作的 
- SELECT_LEX_UNIT类中的个成员变量 fake_select_lex,来保存整个union操作的order by,limit条件。
- 子查询(subselect)
 select子句,from子句,where子句中出现子查询(subselect)的情况:- MySQL解析器会先建一个SELECT_LEX_UNIT,将此SELECT_LEX_UNIT挂在该子查询上一级select对应的SELECT_LEX下(即该SELECT_LEX的slave指针赋值为此SELECT_LEX_UNIT对应的地址);
- 同时新建一个SELECT_LEX和这个子查询对应,将这个新建的SELECT_LEX挂在刚建的SELECT_LEX_UNIT下。 ----level 2;
 
 
 
- 语句 & 存储结构
    
总的执行顺序:FROM > ON > JOIN > WHERE > GROUP BY > HAVING > SELECT > DISTINCT > UNION > ORDER BY > LIMIT
参考:
更多推荐
 
 




所有评论(0)