社区版的MySQL本身不带审计插件,在网上看到有朋友采用mariadb 的审计插件部署到MySQL上来实现审计的功能,作者也测试了一下,发现确实可以使用(但偶尔遇到安装插件时导致数据库重启的问题,计划下周去解决这个问题),然后想把这个插件也部署到MySQL 8.0 上去使用,结果在执行"install plugin  server_audit soname 'server_audit.so' 的时候,就开始报错。这个插件在mysql 8.0 上根本安装不上。 

  

      然后想通过源码来定位,这个插件为什么在mysql 8.0 上安装不上的问题 .

       通过从mariadb的官网上下载了mariadb的10.2.36版本的源码包,解压后将server_audit目录直接复制到mysql 8.0.20的源码里plugin目录下, 简单修改CMakeLists.txt文件后,然后开始编译,结果出现无数的编译错误。看到无尽的满屏错误,尝试采用逮住哪行出错就去修改哪行的"强行纠正"方式一段时间无果后,最终放弃直接在mariadb 的审计插件源码上修改的方式来适配mysql 8.0 ,而是采用在mysql 8.0上重新开发一个插件的思路,逐步将mariadb的审计插件的功能以及基础代码移植过来的方法。同时,在移植过程中,也发现mysql 8.0 跟mysql 5.7 之间的代码,差异已经很大,很多基础的函数也已经发生变化,也可能正是因为如此, mariadb从此跟mysql分道扬镳。


         作者之前确实是简单地研究过MySQL的源代码,但压根没有写过c程序(说出来的有点不好意思),典型的眼高手低。 现在想把mariadb 的审计插件移植到mysql8.0 ,已是大大超出作者能力的事情,也感觉自己不太可能做到,但还是想试一下再看看。 经过一段差点吐血的经历之后, 也深深体会到网上传播的段子“只要思想不滑坡,方法总比困难多” 的通俗跟真实。 


          虽然过程很吐血,但是经历的时间还算短,经过10天左右“折腾”(也是因为能力还不够,也还不太懂数据库内核,所以折腾了这么久),mariadb的审计插件妥妥地移植到mysql 8.0 。同时,作者在server_audit_events 参数中,新增一个支持选项:QUERY_ERROR。该选项的目的是记录执行出错的SQL. 增加这个选项的目的,是出于平时运维数据库过程中遇到的这样的情况:

在平时运维中,偶尔会遇到有同事说数据库有问题(无法操作数据库),但实际情况是应用程序传递了错误的SQL过来,但这种语法错误的SQL,并不记录在数据库的错误日志中,所以排查这种问题的时候,需要开全日志才能发现,但开全日志的时候,会记录所有的sql, 如果日志量太大,也不太容易定位有错误的SQL .  所以,在这次移植审计插件的时候,考虑了这种情况跟需求,并最终实现。


    审计插件沿用了原mariadb插件的使用方式跟参数,(但去掉了syslog选项),如下:

审计插件在社区版MySQL 8.0上适配_java

上面将server_audit_events 设置为CONNECT, QUERY_DDL, QUERY_ERROR,则只记录connect , DDL , 以及执行出错的sql.


执行以下测试:

审计插件在社区版MySQL 8.0上适配_java_02


相关的审计日志:

审计插件在社区版MySQL 8.0上适配_java_03


执行错误的insert 记录在审计日志中,执行成功的insert 没有记录在审计日志中。 


       本想抱着取之开源,回馈开源的精神,在移植后的第一时间点,将源码公开出来。但考虑到审计插件在MySQL企业版上是已有功能。考量之后,暂时决定不公开出来(后面再考虑)。因为作者是专职的运维人员,开发并非专能跟专职,审计插件刚移植完,还没有进行充分的测试。如果有朋友愿意帮忙测试跟试用,将定向分享该插件。