数据库管理提速:SQL解析的探索与应用数据库

来源:互联网 / 作者:SKY / 2018-06-21 15:19 / 点击:
SQL解析是一项复杂的技术,一般都是由数据库厂商来掌握,当然也有公司专门提供SQL解析的API。SQL解析与优化是属于编译器范畴,和C语言等其他语言的解析没有本质

数据库作为核心的基础组件,是需要重点保护的对象。任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失。

为了避免这种损失,一般会在管理上下功夫,比如为研发人员制定数据库开发规范;新上线的SQL,需要DBA进行审核;维护操作需要经过领导审批等等。而且如果希望能够有效地管理这些措施,需要有效的数据库培训,还需要DBA细心的进行SQL审核。很多中小型创业公司可以通过设定规范、进行培训、完善审核流程来管理数据库。

随着美团点评的业务不断发展和壮大,上述措施的实施成本越来越高。如何更多的依赖技术手段,来提高效率,越来越受到重视。业界已有不少基于MySQL源码开发的SQL审核、优化建议等工具,极大的减轻了DBA的SQL审核负担。那么我们能否继续扩展MySQL的源码,来辅助DBA和研发人员来进一步提高效率呢?比如,更全面的SQL优化功能;多维度的慢查询分析;辅助故障分析等。要实现上述功能,其中最核心的技术之一就是SQL解析。

现状与场景

SQL解析是一项复杂的技术,一般都是由数据库厂商来掌握,当然也有公司专门提供SQL解析的API(参考链接:)。

由于这几年MySQL数据库中间件的兴起,需要支持读写分离、分库分表等功能,就必须从SQL中抽出表名、库名以及相关字段的值。因此像Java语言编写的Druid,C语言编写的MaxScale,Go语言编写的Kingshard等,都会对SQL进行部分解析。而真正把SQL解析技术用于数据库维护的产品较少,主要有如下几个:

美团点评开源的SQLAdvisor。它基于MySQL原生态词法解析,结合分析SQL中的where条件、聚合条件、多表Join关系给出索引优化建议。

参考链接:https://github.com/Meituan-Dianping/SQLAdvisor

去哪儿开源的Inception。侧重于根据内置的规则,对SQL进行审核。

参考链接:

阿里的Cloud DBA。根据官方文档介绍,其也是提供SQL优化建议和改写。

参考链接:https://yq.aliyun.com/articles/218442

上述产品都有非常合适的应用场景,在业界也被广泛使用。但是SQL解析的应用场景远远没有被充分发掘,比如:

基于表粒度的慢查询报表。比如,一个Schema中包含了属于不同业务线的数据表,那么从业务线的角度来说,其希望提供表粒度的慢查询报表。

生成SQL特征。将SQL语句中的值替换成问号,方便SQL归类。虽然可以使用正则表达式实现相同的功能,但是其Bug较多,可以参考pt-query-digest。比如pt-query-digest中,会把遇到的数字都替换成“?”,导致无法区别不同数字后缀的表。

高危操作确认与规避。比如,DBA不小心Drop数据表,而此类操作,目前还无有效的工具进行回滚,尤其是大表,其后果将是灾难性的。

SQL合法性判断。为了安全、审计、控制等方面的原因,美团点评不会让研发人员直接操作数据库,而是提供RDS服务。尤其是对于数据变更,需要研发人员的上级主管进行业务上的审批。如果研发人员,写了一条语法错误的SQL,而RDS无法判断该SQL是否合法,就会造成不必要的沟通成本。

因此为了让所有有需要的业务都能方便地使用SQL解析功能,我们认为应该具有如下特性:

直接暴露SQL解析接口,使用尽量简单。比如:输入SQL,则输出表名、特征和优化建议。

接口的使用不依赖于特定的语言,否则维护和使用的代价太高。比如:以HTTP等方式提供服务。

千里之行,始于足下,下面我先介绍下SQL的解析原理。

原理

SQL解析与优化是属于编译器范畴,和C语言等其他语言的解析没有本质的区别。其中分为词法分析、语法和语义分析、优化、执行代码生成。对应到MySQL的部分,如下图:

数据库管理提速:SQL解析的探索与应用

SQL解析原理

1、词法分析

SQL解析由词法分析和语法/语义分析两个部分组成。词法分析主要是把输入转化成一个个Token。其中Token中包含Keyword(也称symbol)和非Keyword。例如:SQL语句select username from userinfo,在分析之后,会得到4个Token,其中有2个Keyword,分别为select和from:

数据库管理提速:SQL解析的探索与应用

通常情况下,词法分析可以使用Flex来生成。

参考链接:https://www.gnu.org/software/flex

但是MySQL并未使用该工具,而是手写了词法分析部分(据说是为了效率和灵活性,可参考:https://yq.aliyun.com/articles/71979)。具体代码在sql/lex.h和sql/sql_lex.cc文件中。

MySQL中的Keyword定义在sql/lex.h中,如下为部分Keyword:

"&&", SYM(AND_AND_SYM)},  

"<", SYM(LT)},  

"<=", SYM(LE)},  

"<>", SYM(NE)},  

"!=", SYM(NE)},  

"=", SYM(EQ)},  

">", SYM(GT_SYM)},  

">=", SYM(GE)},  

"<<", SYM(SHIFT_LEFT)},  

">>", SYM(SHIFT_RIGHT)},  

"<=>", SYM(EQUAL_SYM)},  

"ACCESSIBLE", SYM(ACCESSIBLE_SYM)},  

"ACTION", SYM(ACTION)},  

"ADD", SYM(ADD)},  

"AFTER", SYM(AFTER_SYM)},  

"AGAINST", SYM(AGAINST)},  

"AGGREGATE", SYM(AGGREGATE_SYM)},  

"ALL", SYM(ALL)}, 

词法分析的核心代码在sql/sql_lex.c文件中的MySQLLex→lex_one_Token,有兴趣的同学可以下载源码研究。

2、语法分析

阅读延展

1
3