目录

1. 版本关系

  1. MariaDB与MySQL的版本对应关系
    20210129153333

参考:

  1. mysql&mariadb–Compatibility & Differences

2. MySQL MariaDB 安装

2.1. MariaDB安装

2.1.1. 源码编译安装

使用源码编译后进行安装;

参考:

  1. CentOS7安装MariaDB 10.5.4
  2. centos7 mariadb 10.5.5 源码自动化安装 shell

2.2. docker运行

  1. 安装高版本MariaDB

    1. 配置MariaDB的yum源设置;
    2. 使用yum进行安装或升级;
  2. 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

  • 问题:
    1. 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
      

参考:

  1. docker-mysql官网

3. 文件目录 & 类 概述

3.1. 文件

参考:

  1. MySQL是怎么在源码层表达对象的-----Item对象及子对象解析(一)
  2. MySQL源码分析以及目录结构    //重要;

3.1.1. 头文件

  1. item.h:
    总的对象定义类,定义了’Item’类作为总的对象类,此后,本文件中定义了许多子类,来丰富和发展MySQL可以处理的对象。但此类继承自’Parse_tree_node’类,使得对象和词法语法解析关联起来,这个不细述。

  2. item_cmpfunc.h:
    定义了’Item_bool_func’类,继承自’Item_int_func’类,而Item_int_func继承自Item_func,Item_func类继承自Item类。'Item_bool_func’类主要用于支持比较操作,如等于、大于、小于、IN、BETWEEN、是否为NULL等。

  3. item_create.h:
    用户自定义函数的创建接口。

  4. item_func.h:
    定义了 Item_func类,继承自Item类,用以支持各种函数操作。如求绝对值、求长度、取余等等。本文件中也定义了许多子类,来丰富和发展MySQL可以处理的对象。

  5. item_geofunc.h:
    空间对象处理相关函数。

  6. item_inetfunc.h:
    定义IPv4、IP6的处理。

  7. item_sum.h:
    定义聚集函数的处理。包括MIN和MAX,但通常这2函数个是利用索引进行优化的。

3.2. 类


4. MySQL语句解析器 – lex + yacc

4.1. 概述

  1. 解析过程
    mysql_sql解析过程

  2. 解析器:

    1. mysql是使用了开始的bison(即yacc的开源版)作为sql语法解析器;
    2. 在mysql源码中,解析sql在sql_yacc.yy中实现,而sql_yacc.yy 借助 bison 来转换为c文件。
  3. SQL解析相关文件及关联

    1. 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

    2. SQL语法解析文件:
      sql/sql_yacc.yy、sql/sql_yacc.cc、sql/sql_yacc.h

    3. SQL语句的hint语法解析文件:
      sql/sql_hints.yy、sql/sql_hints.yy.cc


4.2. Lex 词法解析器


4.3. yacc 语法解析器

yacc
bison

参考:

  1. MySQL内核源码解读-SQL解析一  //Bison
  2. 从Mysql源代码角度分析一句简单sql的查询过程 //重要

5. MySQL语句 成员分析

5.1. 语句解析过程

参考:

  1. 用mysql源码进行SQL解析

下文只对常用的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 语句

参考:

  1. MySQL解析器源码分析–对select语句中子查询处理逻辑的分析(一)

5.2.1. select 语句中子查询处理逻辑的分析

  1. 主要数据结构 & 相互关系

    1. select 结构

      • MySQL解析器中负责分析和存储一个select语句信息的数据结构是st_select_lex类(MySQL中同时将该类宏定义为 SELECT_LEX);
      • 同时负责分析和存储union关系的数据结构是st_select_lex_unit类(MySQL中同时将该类宏定义为SELECT_LEX_UNIT);
      • 而这两个类都继承于 st_select_lex_node类
    2. SELECT_LEX类

      1. 对于SELECT_LEX类,它主要是存储一个select语句中select子句的返回列信息,from子句中的表信息,order by,group by子句的列信息等。
      2. 对于本文所关心的问题,SELECT_LEX类使用继承于st_select_lex_node类的 next指针 存储和该select语句进行union操作的其他select语句对应的 SELECT_LEX的地址,通过该指针串成union链表;
  2. 具体存储方式

    1. 语句 & 存储结构
      //见:参考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)
          ------------------------------------------------------------------------
      
    2. 解析:
      1. SELECT_LEX_UNIT 负责管理处于同一级的进行 union操作 的 数个select子句对应的SELECT_LEX
      2. 指针:
        1. SELECT_LEX_UNIT 通过继承于st_select_lex_node类 的 slave指针 存储属于这一级的进行union操作的 第一个SELECT_LEX
        2. 这一级别其他参与union操作的SELECT_LEX,可以通过 next指针 串成的链表依次找到。
      3. SELECT_LEX_UNIT类中的个成员变量 fake_select_lex,来保存整个union操作的order by,limit条件。
      4. 子查询(subselect)
        select子句,from子句,where子句中出现子查询(subselect)的情况:
        1. MySQL解析器会先建一个SELECT_LEX_UNIT,将此SELECT_LEX_UNIT挂在该子查询上一级select对应的SELECT_LEX下(即该SELECT_LEX的slave指针赋值为此SELECT_LEX_UNIT对应的地址);
        2. 同时新建一个SELECT_LEX和这个子查询对应,将这个新建的SELECT_LEX挂在刚建的SELECT_LEX_UNIT下。 ----level 2;

总的执行顺序:
FROM > ON > JOIN > WHERE > GROUP BY > HAVING > SELECT > DISTINCT > UNION > ORDER BY > LIMIT

参考:

  1. MySQL Internals Manual:12.4 Structure Of Complex Select
  2. MySQL解析器源码分析–对select语句中子查询处理逻辑的分析(一)

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐