使用JDBC启用MySQL通用查询日志

使用JDBC启用MySQL通用查询日志,mysql,logging,jdbc,Mysql,Logging,Jdbc,有没有办法通过JDBC启用MySQL通用查询日志记录?我在搜索中发现的最接近于通过JDBC记录慢速查询的能力(http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html). 也许我应该这样做,然后将慢速查询阈值设置为0毫秒 我希望通过MySQL以可读的格式记录所有查询,并指定日志文件应该写入的位置。我知道我会受到性能的影响,但我的应用程序只有一个用户,而且非常简单,如果性能受

有没有办法通过JDBC启用MySQL通用查询日志记录?我在搜索中发现的最接近于通过JDBC记录慢速查询的能力(http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html). 也许我应该这样做,然后将慢速查询阈值设置为0毫秒

我希望通过MySQL以可读的格式记录所有查询,并指定日志文件应该写入的位置。我知道我会受到性能的影响,但我的应用程序只有一个用户,而且非常简单,如果性能受到明显影响,我会感到惊讶。我想试试看


我相信我的另一个选择是打开二进制日志并使用mysqlbinlog将二进制日志转换为人类可读的格式,但听起来通用查询日志将提供一种更简单的方式来获取我想要的内容。

如果您使用Hibernate,并通过它执行所有数据访问,您可以通过将属性
hibernate.show\u sql
设置为true来打开日志记录。这将编写参数化语句(例如,从foo中选择foo.id,其中foo.bar=?)。如果您需要参数值,或者不使用Hibernate之类的工具,则可能需要让MySQL编写此日志。请参阅上的MySQL文档

FWIW,MySQL二进制日志是达到不同目的的一种手段;它记录对数据的更改,并用于增量备份和/或复制<代码>选择语句不会记录在二进制日志中

编辑: 通过在my.cnf中添加以下两行代码(在确认两个变量均未设置后),并重新启动MySQL,我可以让MySQL编写常规日志:


general_log = 1
general_log_file=/tmp/mysql-general.log

我最终找到了一个解决办法。我通过Java在运行时使用以下SQL查询修改MySQL全局系统变量来启用MySQL通用查询日志记录

SET GLOBAL log_output="FILE"
SET GLOBAL general_log_file="Path/File"
SET GLOBAL general_log='ON'
我建议在常规日志文件路径中使用前斜杠。我无法让反斜杠工作,即使在Windows环境中也是如此

我使用以下SQL查询在运行时禁用常规查询日志记录

SET GLOBAL general_log='OFF'

您可以如下方式启用JDBC URL中的日志记录:

jdbc:mysql://host/db?logger=com.mysql.jdbc.log.Log4JLogger&profileSQL=true
其他日志后端可用(CommonLogger、Slf4jLogger、JDK14Logger)。我相信由于许可问题,DirectLog4J日志记录在某个时候被删除了,所以它可能无法与您的JDBC驱动程序版本一起工作

当然,在类路径中需要相关日志库的JAR和一个配置文件(log4j.properties)。我会首先将根级别设置为TRACE,以查看发生了什么,并在看到记录的内容后按日志级别和类别将其收紧

进一步阅读:


HTH

将“logger”和“profileSQL”添加到jdbc url:

&logger=com.mysql.jdbc.log.Slf4JLogger&profileSQL=true
然后您将得到下面的SQL语句:

2016-01-14 10:09:43  INFO MySQL - FETCH created: Thu Jan 14 10:09:43 CST 2016 duration: 1 connection: 19130945 statement: 999 resultset: 0
2016-01-14 10:09:43  INFO MySQL - QUERY created: Thu Jan 14 10:09:43 CST 2016 duration: 1 connection: 19130945 statement: 999 resultset: 0 message: SET sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'
2016-01-14 10:09:43  INFO MySQL - FETCH created: Thu Jan 14 10:09:43 CST 2016 duration: 1 connection: 19130945 statement: 999 resultset: 0
2016-01-14 10:09:43  INFO MySQL - QUERY created: Thu Jan 14 10:09:43 CST 2016 duration: 2 connection: 19130945 statement: 13 resultset: 17 message: select 1
2016-01-14 10:09:43  INFO MySQL - FETCH created: Thu Jan 14 10:09:43 CST 2016 duration: 0 connection: 19130945 statement: 13 resultset: 17
2016-01-14 10:09:43  INFO MySQL - QUERY created: Thu Jan 14 10:09:43 CST 2016 duration: 1 connection: 19130945 statement: 15 resultset: 18 message: select @@session.tx_read_only
2016-01-14 10:09:43  INFO MySQL - FETCH created: Thu Jan 14 10:09:43 CST 2016 duration: 0 connection: 19130945 statement: 15 resultset: 18
2016-01-14 10:09:43  INFO MySQL - QUERY created: Thu Jan 14 10:09:43 CST 2016 duration: 2 connection: 19130945 statement: 14 resultset: 0 message: update sequence set seq=seq+incr where name='demo' and seq=4602
2016-01-14 10:09:43  INFO MySQL - FETCH created: Thu Jan 14 10:09:43 CST 2016 duration: 0 connection: 19130945 statement: 14 resultset: 0
默认记录器为:

com.mysql.jdbc.log.StandardLogger

Mysql jdbc属性列表:

使用Mysql和Mysql-connector-java-8.0.13.jar,我在我的jdbc连接URL中添加了
profileSQL=true
。例如:

jdbc:mysql://${HOST}:${PORT}/${SCHEMA}?autoReconnect=true&profileSQL=true
您还可以将
&logger=com.mysql.cj.log.StandardLogger
添加到URL,但不需要,因为它是文档中指定的默认值

文件参考:


日志输出读取起来很烦人,因为它包含一个堆栈跟踪,指示查询在代码中的确切位置运行。如果有人想办法排除堆栈跟踪,请告诉我。

对于Spring Boot的最新MySQL驱动程序版本,请添加到JDBC连接URL:

spring.datasource.url:jdbc:mysql://localhost:49172/INTEGRATION_DB?logger=com.mysql.cj.log.Slf4JLogger&profileSQL=true
它将使用Slf4J记录器。如果没有这样的记录器,可以使用标准记录器:
logger=com.mysql.cj.log.StandardLogger


也可以使用自定义记录器,只需实现接口
com.mysql.cj.log.log
,并在连接URL中指定一个新的记录器。

Eric,我从来没有看到过mysql的一页官方文档是可以理解的,我已经使用了5年了。我可以非常具体地指出这一页上的模糊性。您能否显示一个用于打开常规查询日志的查询示例?我也不知道我是否使用hibernate。如果你能告诉我如何检查,我可以让你知道。谢谢!这实际上是在使用不容易支持添加日志参数的blackbox/封闭源代码框架时。注意,由于许可证不兼容,Log4JLogger显然不再包含在Connector/J中,而是Slf4JLogger(它有大写字母J,而不是上面建议的小写字母)仍然可用,如果存在,将通过log4j进行日志记录。日志包最近已移动到
com.mysql.cj.log
,例如
com.mysql.cj.log.Slf4JLogger
,看起来这将记录对服务器的查询。如果您没有对运行MySQL的服务器的登录权限,这将不会有帮助。如果这些是您唯一的连接参数,您应该使用“?logger=com.MySQL.jdbc.log.Slf4JLogger&profileSQL=true”(否则jdbc代码会将DB名称与行的其余部分连接起来)在类路径中需要slf4j api和slf4j simple。默认情况下,StandardLogger可以省略它。第一个参数需要一个?而不是&as与任何URI一样。但对我来说仍然不起作用。从
com.mysql.cj.util.LogUtils.expandProfilerEventIfNecessary(LogUtils.java:53)
引发错误。知道吗?这是我在回答中提到的堆栈跟踪的一部分。如果深入查看堆栈跟踪,它将告诉您执行查询的代码行。我只是再试了一次,最初认为有问题,但我的应用程序仍然运行,它仍然输出正在运行的查询。如果有一个省略堆栈跟踪的解决方案,那将是理想的。