【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)