SQL审核工具SQL Advisor简单体验
现在的很多大公司,都喜欢招丰富经验的人,从公司的角度来说,能把当前的事务性工作解决了,在这个基础上能够把你的理解和知识沉淀下来,那是极好的,说通俗一些,算是吸星大法了。
我和雪刚相识于几年前的一次技术沙龙,当时是邀请他来做的一起关于监控报警的分享,时间一晃几年就过去了。技术圈已经有了很大的变化,在SQL审核领域,开源工具SQL Advisor中也看到了雪刚的贡献。
GitHub上来看下这个项目的情况,star有2000多,还是比较高的了。在工具的更新和活跃度上,貌似有了停滞的进度。
对于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审核,源码文档中也给出了一些很细致的流程说明,还有更多的流程说明图,对于我们后续来定制和使用也是一种很不错的参考借鉴。