SQL审核工具SQL Advisor简单体验

 现在的很多大公司,都喜欢招丰富经验的人,从公司的角度来说,能把当前的事务性工作解决了,在这个基础上能够把你的理解和知识沉淀下来,那是极好的,说通俗一些,算是吸星大法了。

 我和雪刚相识于几年前的一次技术沙龙,当时是邀请他来做的一起关于监控报警的分享,时间一晃几年就过去了。技术圈已经有了很大的变化,在SQL审核领域,开源工具SQL Advisor中也看到了雪刚的贡献。

    GitHub上来看下这个项目的情况,star有2000多,还是比较高的了。在工具的更新和活跃度上,貌似有了停滞的进度。

SQL审核工具SQL Advisor简单体验

对于SQL审核,一直以来我觉得审核的价值是性能和潜在问题,语法问题严格意义上来说不属于审核的范畴,但是让我捉急的是,我们却需要花很多的工具在权限,语法上,希望这款工具能给我一些新的视角。

要体验下这个工具,整个过程我用了差不多半个多小时就部署跑通了。

简单来说下这个过程吧。

前期是要安装一些基本的软件包。

yum   install cmake libaio-devel libffi-devel glib2 glib2-devel

接下来编辑的过程有点类似源码安装MySQL。我们需要把sqlparser编译到/usr/local/sqlparser路径下。

 cmake -DBUILD_CONFIG=mysql_release -DCMAKE_BUILD_TYPE=debug -DCMAKE_INSTALL_PREFIX=/usr/local/sqlparser ./

 make

 make install

整个过程相对很快。

然后我们到sqladvisor的目录下,编译安装sqladvisor

一个测试的目录结构如下:

/root/sqladvisor/SQLAdvisor/sqladvisor

目录下的文件是下面的样子:

 [[email protected] sqladvisor]# ll 

total 60

-rw-r--r-- 1 root root   694 Jun 26 22:14 CMakeLists.txt

-rw-r--r-- 1 root root 53195 Jun 26 22:14 main.cc

-rw-r--r-- 1 root root   257 Jun 26 22:14 README

开始编译:

 cmake -DCMAKE_BUILD_TYPE=debug ./ 

如果MySQL的配置不对,很可能在make阶段出错,这个错误根本上来说还是链接库的缺失。

[[email protected] sqladvisor]# make 

Scanning dependencies of target sqladvisor

[100%] Building CXX object CMakeFiles/sqladvisor.dir/main.cc.o

Linking CXX executable sqladvisor

/usr/bin/ld: cannot find -lperconaserverclient_r

collect2: ld returned 1 exit status

make[2]: *** [sqladvisor] Error 1

make[1]: *** [CMakeFiles/sqladvisor.dir/all] Error 2

make: *** [all] Error 2

在/usr/lib64下面找不到对应的链接库,我们可以手工配置一下即可。

如果你安装的是Percona分支的话,可以使用如下的步骤:

1. cd /usr/lib64/ 

2. ln -s libperconaserverclient_r.so.18 libperconaserverclient_r.so

我安装的是社区版本,版本更新一些,所以简单可以这种修改下。

[[email protected] lib]# ll 

total 1003112

-rw-r--r-- 1 root root  20051248 Nov 22  2017 libmysqlclient.a

-rwxr-xr-x 1 root root   9255841 Nov 22  2017 libmysqlclient.so

-rwxr-xr-x 1 root root   9255841 Nov 22  2017 libmysqlclient.so.20

-rwxr-xr-x 1 root root   9255841 Nov 22  2017 libmysqlclient.so.20.3.6

创建链接库:

[[email protected] lib]# cp libmysqlclient.so.20 /usr/lib64/

ln -s libmysqlclient.so.20 libperconaserverclient_r.so

再次编译就没有问题了。

[[email protected] sqladvisor]# make

Linking CXX executable sqladvisor

[100%] Built target sqladvisor

当然对于使用来说,为了更方便,我们可以创建个软链接。

ln -s sqladvisor /usr/bin/

基本到了这一步,就能证明我们的软件安装成功了。

[[email protected] sqladvisor]# ./sqladvisor --help 

Usage:

  sqladvisor [OPTION...] sqladvisor

SQL Advisor Summary

Help Options:

  -?, --help              Show help options

Application Options:

  -f, --defaults-file     sqls file

  -u, --username          username

  -p, --password          password

  -P, --port              port

  -h, --host              host

  -d, --dbname            database name

  -q, --sqls              sqls

  -v, --verbose           1:output logs 0:output nothing

从整个部署和脚本的情况来看,它是一种在线监测。

比如我们创建一个数据库testdb,然后写个简单的SQL来看看效果。

初始化数据:

mysql> use testdb

Database changed

mysql> create table t2(id int primary key,name varchar(30));

Query OK, 0 rows affected (0.08 sec)

mysql> insert into t2 values(1,'aa'),(2,'bb'),(3,'cc');

Query OK, 3 rows affected (0.09 sec)

Records: 3  Duplicates: 0  Warnings: 0

使用如下的命令后,可以看到SQL审核后的结果如下:

[[email protected] sqladvisor]# ./sqladvisor  -h 127.0.0.1 -u root -p xxxx -P 3306 -d testdb -q "select * from t2 where id=3;" -v 1

2018-06-26 22:31:15 26531 [Note] 第1步: 对SQL解析优化之后得到的SQL:select `*` AS `*` from `testdb`.`t2` where (`id` = 3) 

2018-06-26 22:31:15 26531 [Note] 第2步:开始解析where中的条件:(`id` = 3) 

2018-06-26 22:31:15 26531 [Note] show index from t2 

2018-06-26 22:31:15 26531 [Note] 第3步:SQLAdvisor结束!错误日志:

然后我们删除主键,查看效果是否有差别。

mysql> alter table t2 drop primary key;

Query OK, 3 rows affected (0.13 sec)

Records: 3  Duplicates: 0  Warnings: 0

结果如下:

[[email protected] sqladvisor]# ./sqladvisor  -h 127.0.0.1 -u root -p xxxx -P 3306 -d testdb -q "select * from t2 where id=3;" -v 1

2018-06-26 22:32:38 26539 [Note] 第1步: 对SQL解析优化之后得到的SQL:select `*` AS `*` from `testdb`.`t2` where (`id` = 3) 

2018-06-26 22:32:38 26539 [Note] 第2步:开始解析where中的条件:(`id` = 3) 

2018-06-26 22:32:38 26539 [Note] show index from t2 

2018-06-26 22:32:38 26539 [Note] 第3步:SQLAdvisor结束!表中没有任何索引 

可见效果是预期中的。

当然也可以使用配置文件来运行。创建配置文件sql.cnf:

[[email protected] sqladvisor]# vi sql.cnf

[sqladvisor]

username=root

password=xxxx

host=127.0.0.1

port=3306

dbname=testdb

sqls=select * from t2 where id=3;

整个SQL审核后的结果如下:

[[email protected] sqladvisor]# ./sqladvisor  -f sql.cnf -v 1

2018-06-26 22:33:37 26544 [Note] 第1步: 对SQL解析优化之后得到的SQL:select `*` AS `*` from `testdb`.`t2` where (`id` = 3) 

2018-06-26 22:33:37 26544 [Note] 第2步:开始解析where中的条件:(`id` = 3) 

2018-06-26 22:33:37 26544 [Note] show index from t2 

2018-06-26 22:33:37 26544 [Note] 第3步:SQLAdvisor结束!表中没有任何索引 

如果创建一个辅助索引,这个时候的检测结果有些奇怪,这个部分我后续要再琢磨下这个逻辑,看看有没有改进的空间。

mysql> alter table t2 add key idx_t2_id(id);

[[email protected] sqladvisor]#  ./sqladvisor  -h 127.0.0.1 -u root -p tesatch -P 3306 -d testdb -q "select * from t2 where id=3;" -v 1

2018-06-26 23:12:36 26734 [Note] 第1步: 对SQL解析优化之后得到的SQL:select `*` AS `*` from `testdb`.`t2` where (`id` = 3) 

2018-06-26 23:12:36 26734 [Note] 第2步:开始解析where中的条件:(`id` = 3) 

2018-06-26 23:12:36 26734 [Note] show index from t2 

2018-06-26 23:12:36 26734 [Note] 第3步:SQLAdvisor结束!表中没有任何索引 

而如果使用了drop选项,这个时候就放大招了。:)

[[email protected] sqladvisor]# ./sqladvisor  -h 127.0.0.1 -u root -p tematch -P 3306 -d testdb -q "drop table t2 ;" -v 1 

2018-06-26 22:39:17 26582 [Note] 第1步: 对SQL解析优化之后得到的SQL:select  from dual where 1 having 1 

2018-06-26 22:39:17 26582 [Note] 第2步:表t2 的SQL太逆天,没有优化建议 

2018-06-26 22:39:17 26582 [Note] 第3步: SQLAdvisor结束! 

对于SQL审核,源码文档中也给出了一些很细致的流程说明,还有更多的流程说明图,对于我们后续来定制和使用也是一种很不错的参考借鉴。

SQL审核工具SQL Advisor简单体验