记录 MySQL 数据库更改查询和用户

Bea*_*eat 5 mysql logs

出于安全原因,我需要在服务器端(运行 Debian 6.0 Squeeze)记录所有可能更改 MySQL DB(v. 5.1)内容的查询以及发布它的用户。我不得不排除

  • 由于性能问题的通用查询日志(它记录了所有内容,而且 IO 太多)
  • 二进制日志,因为它不记录用户的姓名。
  • 使用诸如ngrep捕获网络流量和过滤器之类的工具UPDATEDELETE因为这会让我处理事务并且我不知道收到的查询是否真的被执行了。

我找不到任何可以让我更改 MySQL 固有日志行为的设置,因此我正在寻找其他解决方案。到目前为止,我提出了两种可能性:

  • 将一般查询日志写入命名管道并将过滤器和写入器附加到管道的另一端 - 但我担心这...
  • 将相关日志分别传输到服务器,但那样我必须发送查询两次(一次用于数据库,一次用于日志记录),很难确保日志与数据库同步(事务、锁等) .),并且出于安全原因,信任客户端真正发送日志可能是不明智的

背景:

  • 用户通过 Java 桌面应用程序访问数据库,该应用程序打开到 MySQL 服务器的 SSH 隧道
  • 我使用 EclipseLink 作为持久性提供者
  • 该应用程序大量使用事务
  • 服务器在共享环境中运行

您对如何执行我的日志记录有更好的想法吗?

Ica*_*sNM 4

  1. 对我来说,这听起来像是TRIGGERS的完美运用。你说你有事务,所以你一定已经在使用InnoDB了。在您关心的表上附加 INSERT、UPDATE 和 DELETE 触发器,每个触发器都会在表事件发生后触发对日志表的 INSERT。您的 SELECT 过滤器就完成了。您还可以完全控制记录内容和方式。

    这是一个更高级别的解决方案,更接近应用程序层,而不是拥有完整 SQL 查询的精确副本的低级别系统日志解决方案。但我认为它确实解决了您的一些担忧。

    InnoDB触发器可以访问存储过程和所有MySQL函数,所以我猜你可以在其中找到用户的登录名。日志时间就是 NOW()。

    您最终可能需要管理很多触发器,具体取决于表的数量,但这只是每个触发器的复制/粘贴工作。我在单个参考 SQL 文件中维护所有触发器的代码以及该数据库的表定义和视图。

    我从未在事务丰富的环境中测试过触发器以确保触发器仅在事务提交后触发。文档在这个主题上很薄弱,但他们确实说:“只有当 BEFORE 触发器(如果有)和行操作都成功执行时,才会执行 AFTER 触发器。” 对我来说听起来很确定。现在您也知道您没有记录实际上不起作用的事情。

  2. 或者设置复制,如果需要,甚至可以复制到同一机器上的另一个 mysqld 实例。打开从属实例上的 mysqld 完整查询日志记录。失败的事务不会被复制,SELECT 也不会被复制。