18

有没有办法通过 JDBC 启用 MySQL 通用查询日志记录?我通过搜索找到的最接近的东西是能够通过 JDBC 记录慢速查询 (http://dev.mysql.com/doc/refman/5.5/en/connector-j-reference-configuration-properties.html)。也许我应该这样做并将慢查询阈值设置为 0 毫秒?

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

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

4

6 回答 6

33

您可以像这样在 JDBC URL 中启用日志记录:

jdbc:mysql://host/db?logger=com.mysql.jdbc.log.Log4JLogger&profileSQL=true

其他日志后端可用(CommonsLogger、Slf4jLogger、JDK14Logger)。我相信由于许可问题,直接 Log4J 日志记录在某些时候被丢弃,因此它可能不适用于您的 JDBC 驱动程序版本。

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

进一步阅读:

高温高压

于 2012-10-23T07:30:54.683 回答
14

将“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 属性列表:https ://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html

于 2016-01-14T02:19:08.400 回答
3

如果您正在使用 Hibernate,并通过它执行所有数据访问,则可以通过将属性设置为 true 来打开日志记录hibernate.show_sql。不过,这将编写参数化语句(例如SELECT foo.id FROM foo WHERE foo.bar = ?)。如果您需要参数值,或者不使用 Hibernate 之类的工具,您可能需要让 MySQL 写入此日志。请参阅一般查询日志上的 MySQL 文档。

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

编辑: 我能够通过将以下两行添加到 my.cnf (在确认两个变量都没有设置之后)并重新启动 MySQL 来让 MySQL 写入常规日志:


general_log = 1
general_log_file=/tmp/mysql-general.log
于 2012-06-05T19:07:58.213 回答
3

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

SET GLOBAL log_output="FILE"
SET GLOBAL general_log_file="Path/File"
SET GLOBAL general_log='ON'

我建议在 general_log_file 路径中使用正斜杠。即使在 Windows 环境中,我也无法使用反斜杠。

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

SET GLOBAL general_log='OFF'
于 2012-07-24T22:52:49.917 回答
0

将 MySQL 与mysql-connector-java-8.0.13.jar一起使用,我将其添加profileSQL=true到我的 JDBC 连接 URL。例如:

jdbc:mysql://${HOST}:${PORT}/${SCHEMA}?autoReconnect=true&profileSQL=true

您也可以添加&logger=com.mysql.cj.log.StandardLogger到 URL,但不是必需的,因为它是文档中指示的默认值。

文档参考:

https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-configuration-properties.html

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

于 2019-10-30T19:40:34.877 回答
0

对于 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 中指定一个新的记录器。

于 2021-04-27T13:52:30.167 回答