繁体   English   中英

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

[英]Enabling MySQL general query log with JDBC

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

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

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

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

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

其他日志后端可用(CommonsLogger、Slf4jLogger、JDK14Logger)。 我相信由于许可问题,直接 Log4J 日志记录在某些时候被删除,因此它可能不适用于您的 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 属性列表: https : //dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html

如果您正在使用 Hibernate,并通过它执行所有数据访问,您可以通过将属性hibernate.show_sql设置为 true 来打开日志记录。 不过,这将编写参数化语句(例如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

我最终找到了解决方法。 我通过使用以下 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'

使用 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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM