mysql - 重用 MySQL 解析器

标签 mysql sql parsing syntax lexical

我正在处理 SQL intrusion detection system (IDS)我需要解析传入的 SQL 查询。编写自己的 SQL 解析器是一项长期任务,它永远不会准确反射(reflect) native 解析器中使用的逻辑。 我发现 MySQL 有一个主源文件 sql/sql_lex.cc 的词法分析器和一个用来自 sql/sql_yacc.y 的 bison 构建的语法分析器。我真的很想重用这个强大的解决方案。我正在用 C/C++ 构建我的 IDS,所以我正在寻找一些方法将 MySQL 解析器与我的检测系统连接起来。

我想知道是否可以重用 MySQL 解析器(词法+语法分析器)以某种逻辑形式获取 SQL 查询的结构,例如语法树。这有没有可能?有相关的文字、教程或项目吗?

谢谢

最佳答案

作为学士项目的一部分,我已经完成了 IDS 的第一个版本。它作为 MySQL 的插件实现。

我将在下面列出我理解 MySQL 内部结构的主要来源。然后我简要描述了我在 IDS 中使用的方法。

MySQL 文档文本

  • 我找到了 Charles BellExpert MySQLSasha PachevUnderstanding MySQL Internals(如 user3822447 所写) 是了解 MySQL 内部结构的非常好的切入点。
  • MySQL 5.1 插件开发Andrew Hutchings 和 Sergei Golubchik 编写,也非常有用。
  • MySQL Internals Manual 还包含一些适合入门的基本信息。
  • 阅读所有内容后,我进行了一些调试(使用 VS)并发现了查询树结构的样子。

我的 IDS 解决方案

我的解决方案的源代码可以在 sourceforge 找到。我计划在其 wiki 中对其进行更多记录。

主要入口点是 audit_ids.cc 中的 audit_ids_notify() 函数。该插件采用内部 MySQL 解析器生成的查询树,并对其进行了简化(以节省内存)。然后它进行异常检测——它有一个已知查询树结构的列表,并保留关于每个查询树结构的每个参数化部分的一些统计信息。输出被写入MySQL数据目录中的特殊日志文件。

我试图使解决方案模块化和可扩展。初始版本是一种演示,性能没有优化,尤其是在 SQL 存储模块中。

MySQL 插件类型

我确定了 2 种可能的方法并使用了第一种。

  1. 审计插件
    • 我的解决方案插件中的包装类型是 audit plugin .
    • 尽管用于报告服务器操作(例如记录查询或错误),我还是使用了这种类型的插件。
    • 我选择这种类型的插件是因为我发现这是唯一支持 native 支持的插件,当查询树在完成(即解析)之后和从内存中释放之前调用(对于 MySQL 5.6.17 ).
    • 缺点:在未来的 MySQL 版本中不能完全保证以上内容,但我认为这在不久的将来应该不会改变。
    • 优点:MySQL不需要重新编译。构建和安装插件就足够了。

  1. 查询重写插件
    • 还有一种替代方法使用非本地插件类型 query-rewrite 。它提供了用于修改查询的插件 API,因此也用于读取查询。
    • 缺点:要支持此插件 API,MySQL 服务器必须使用该 API 重新编译。我认为可能会成为 MySQL 生产发行版的一部分。
    • 优点:专为读取/重写内部查询树而设计的插件类型。

如果有与此主题相关的问题/问题,我可以随时回答;)

关于mysql - 重用 MySQL 解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23038620/

相关文章:

mysql - sqlite - 我如何随机分组订购?

parsing - 编辑时快速词法分析

mysql - 我应该使用子查询还是组合 WHERE?

mysql - 修复mysql中的表

mysql - 如何使用字段的最大值编写更新查询?

c# - decimal.Parse 无法在 visual studio 2012 中使用

c++ - 如何用C++读取CSV文件

php - mysql_real_escape_string() 坏了吗?

php - 尝试在我列出内容的 View 中创建类别明智的过滤并在 php 中收到错误?

php - 选中复选框时如何为 SQL 表提供样式?