记录mysql中的所有查询

358

我能否在我的 MySQL 数据库上开启审计日志记录?

我想要监控所有查询一个小时,并将日志转储到文件中。


8
重复问题 https://dev59.com/N3RB5IYBdhLWcg3wWGEH - Tomas
为了读者的好处:不要错过上面评论中的问题。 - claws
你可以参考我在这里发布的现有答案:http://dba.stackexchange.com/a/62477/6037 - Peter Venderberghe
要在不重启 MySQL 的情况下打开或关闭日志记录,请参见 此答案 - ToolmakerSteve
8个回答

276

除了我在这里遇到的情况,运行以下命令是将查询转储到日志文件而无需重新启动的最简单方法。

SET global log_output = 'FILE';
SET global general_log_file='/Applications/MAMP/logs/mysql_general.log';
SET global general_log = 1;

可以关闭

SET global general_log = 0;

10
非常喜欢这个,适用于已有和新建的数据库连接。 - Carlton
1
有一些统计条目 - 不确定是什么,但除此之外,工作得非常好。 - Snowcrash
1
为了使此功能正常工作,您的用户必须拥有SUPER特权,这是全局DB特权,因此无法限制为特定模式或表:GRANT SUPER ON *.* TO user1@localhost - RobM
如果可以的话,我会给它点赞多次,我有一个书签指向这里 :) 非常感谢! - resi
状态更新:这仍然是我最喜欢的书签之一 :) - resi
显示剩余3条评论

265
注意:对于mysql-5.6+,以下方法将无法生效。如果您需要针对mysql-5.6+的解决方案,请向下滚动点击此处。)

如果您不想或不能重启MySQL服务器,则可以在运行中的服务器上按照以下步骤进行:

  • mysql数据库上创建日志表。
  CREATE TABLE `slow_log` (
   `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
                          ON UPDATE CURRENT_TIMESTAMP,
   `user_host` mediumtext NOT NULL,
   `query_time` time NOT NULL,
   `lock_time` time NOT NULL,
   `rows_sent` int(11) NOT NULL,
   `rows_examined` int(11) NOT NULL,
   `db` varchar(512) NOT NULL,
   `last_insert_id` int(11) NOT NULL,
   `insert_id` int(11) NOT NULL,
   `server_id` int(10) unsigned NOT NULL,
   `sql_text` mediumtext NOT NULL,
   `thread_id` bigint(21) unsigned NOT NULL
  ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'

  CREATE TABLE `general_log` (
   `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
                          ON UPDATE CURRENT_TIMESTAMP,
   `user_host` mediumtext NOT NULL,
   `thread_id` bigint(21) unsigned NOT NULL,
   `server_id` int(10) unsigned NOT NULL,
   `command_type` varchar(64) NOT NULL,
   `argument` mediumtext NOT NULL
  ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
  • 在数据库上启用查询日志记录
SET global general_log = 1;
SET global log_output = 'table';
  • 查看日志
select * from mysql.general_log
  • 禁用数据库的查询日志
SET global general_log = 0;

17
我不确定对于每个版本的MySQL都适用(我使用的是5.5版本),但我不需要创建表。我按照这里提到的建议,省略了创建表的步骤:https://dev59.com/N3RB5IYBdhLWcg3wWGEH#678310 - Tyler Collier
也许它已经因为某种原因被创建了,@TylerCollier - Alexandre Marcondes
4
需要注意的是,如果表尚未存在,则应在mysql数据库上执行CREATE TABLE命令,而不是在任何用户创建的数据库上执行。也许可以更新SQL语句以反映这一点。 - Robert Rossmann
2
查看日志最好使用 SELECT * FROM mysql.general_log order by (event_time) desc。只是说一下。:-) - vinrav
1
不同意 注释 - 在服务器版本5.6.37上完全正常工作。谢谢。 - Dmitriy Olhovsky
要知道日志记录是否启用:SHOW VARIABLES LIKE 'general_log'; - Groco

178

更新:对于MySQL 5.6+已不再有效。

使用--log选项启动mysql:

mysqld --log=log_file_name

或者将以下内容放置在您的my.cnf文件中:

log = log_file_name

你可以使用--log-slow-queries选项来仅记录慢查询,而不是使用--log选项记录所有查询到log_file_name中。默认情况下,执行时间超过10秒的查询被认为是慢查询,你可以通过将long_query_time设置为查询必须执行的秒数来更改此设置。


73
不用说,但在生产环境中保持它开启会很快变得无聊。g - ceejayoz
6
如果您在此方式下无法启用日志记录,请仔细检查MySQL用户是否可以写入适当的文件位置。 - Jon Topper
3
能否仅记录一个特定数据库/表上的查询? - Temujin
2
@Temujin phpmyadmin现在有一个“跟踪”选项,用于指定一个日志(“版本”),它将记录影响该表的查询,并提供有关时间和整个查询的信息。 - gadget00
4
这个被接受的答案应该被删除或编辑,以反映它无法与MySQL 5.6.+一起使用的事实。 - itoctopus
显示剩余5条评论

168

在MySQL 5.6+中,顶部答案无效。请改用以下方法:

[mysqld]
general_log = on
general_log_file=/usr/log/general.log

在你的my.cnf / my.ini文件中

Ubuntu/Debian: /etc/mysql/my.cnf
Windows: c:\ProgramData\MySQL\MySQL Server 5.x
wamp: c:\wamp\bin\mysql\mysqlx.y.z\my.ini
xampp: c:\xampp\mysql\bin\my.ini.


1
如果您使用过它,能否告诉我上述内容的性能影响,并且启用这种方式记录日志是否明智? - Ramesh Pareek
1
Ramesh的性能影响似乎在5-15%的性能下降左右。更多信息请参见https://www.percona.com/blog/2009/02/10/impact-of-logging-on-mysql%E2%80%99s-performance/。 - Firze
1
我不明白为什么Mysql 5.6不允许从查询中设置日志文件?当您只有phpMyAdmin而没有访问服务器目录树时,如何在MySQL 5.6及更高版本中记录所有查询? - Vicky Dev
在这些更改后,从XAMPP控制面板重新启动MySQL服务。 - Paramjeet
这在我的本地Xampp Apache环境中适用,但我仍然需要通过phpMyAdmin打开日志记录。此外,它不能在/usr/log文件夹中找到文件,也无法创建文件,但作为 "general_log_file = filename.log "完全正常。 - JoeP
不要忘记重新启动MySQL服务器 sudo systemctl restart mysqld - M at

57

启用表的日志记录

mysql> SET GLOBAL general_log = 'ON';
mysql> SET GLOBAL log_output = 'table';

通过选择查询查看日志

SELECT * FROM mysql.general_log
如果查询太多,截断表格:
TRUNCATE table mysql.general_log;

有没有通配符可以记录所有表格?(有相当多的表格 :C) - RicardoE
谢谢,这个设置对我非常有用,因为我无法关闭mysql-server。我还希望日志出现在日志表中。 - Gunnar Sigfusson
1
这个表有一个名为“thread_id”的列,它有助于区分特定会话中的查询问题,而不是针对整个数据库发出的所有查询的转储,这就是你在mysql.general_log表上进行SELECT查询时得到的内容。 - itsraghz

22

快速启用MySQL常规查询日志而无需重新启动。

mysql> SET GLOBAL general_log_file = '/var/www/nanhe/log/all.log';
mysql> SET GLOBAL general_log = 'ON';

我通过Homebrew安装了MySQL,MySQL版本为mysql Ver 14.14 Distrib 5.7.15,适用于osx10.11 (x86_64)的EditLine包装器。


8

值得一提的是,general_log 和 slow_log 是在5.1.6版本中引入的:

http://dev.mysql.com/doc/refman/5.1/en/log-destinations.html

5.2.1. 选择常规查询和慢查询日志输出目标
自 MySQL 5.1.6 起,如果启用这些日志,则 MySQL Server 可以灵活控制常规查询日志和慢查询日志的输出目标。日志条目的可能目标是日志文件或 mysql 数据库中的 general_log 和 slow_log 表。

6

操作系统/MySQL版本:

$ uname -a
Darwin Raphaels-MacBook-Pro.local 15.6.0 Darwin Kernel Version 15.6.0: Thu Jun 21 20:07:40 PDT 2018; root:xnu-3248.73.11~1/RELEASE_X86_64 x86_64

$ mysql --version
/usr/local/mysql/bin/mysql  Ver 14.14 Distrib 5.6.23, for osx10.8 (x86_64) using  EditLine wrapper

添加日志记录(例如,我认为/var/log/...不是Mac OS上最好的路径,但它可以工作:

sudo vi ./usr/local/mysql-5.6.23-osx10.8-x86_64/my.cnf

[mysqld]
general_log = on
general_log_file=/var/log/mysql/mysqld_general.log

重启 Mysql

结果:

$ sudo tail -f /var/log/mysql/mysqld_general.log
181210  9:41:04    21 Connect   root@localhost on employees
           21 Query /* mysql-connector-java-5.1.47 ( Revision: fe1903b1ecb4a96a917f7ed3190d80c049b1de29 ) */SELECT  @@session.auto_increment_increment AS auto_increment_increment, @@character_set_client AS character_set_client, @@character_set_connection AS character_set_connection, @@character_set_results AS character_set_results, @@character_set_server AS character_set_server, @@collation_server AS collation_server, @@collation_connection AS collation_connection, @@init_connect AS init_connect, @@interactive_timeout AS interactive_timeout, @@license AS license, @@lower_case_table_names AS lower_case_table_names, @@max_allowed_packet AS max_allowed_packet, @@net_buffer_length AS net_buffer_length, @@net_write_timeout AS net_write_timeout, @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type, @@sql_mode AS sql_mode, @@system_time_zone AS system_time_zone, @@time_zone AS time_zone, @@tx_isolation AS transaction_isolation, @@wait_timeout AS wait_timeout
           21 Query SET NAMES latin1
           21 Query SET character_set_results = NULL
           21 Query SET autocommit=1
           21 Query SELECT USER()
           21 Query SELECT USER()
181210  9:41:10    21 Query show tables
181210  9:41:25    21 Query select count(*) from current_dept_emp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接