MySQL慢查询日志

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介:

1.错误日志:记录启动、运行或停止mysqld时出现的问题。

2.通用查询日志:记录建立的客户端连接和执行的语句。

3.更新日志:记录更改数据的语句。该日志在MySQL 5.1中已不再使用。

4.二进制日志:记录所有更改数据的语句。还用于主从复制。

5.慢查询日志:记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。

6.Innodb日志:innodb redo log

7.中继日志:从库从主库获取到的要更新的数据的日志。

默认情况下,所有日志创建于mysqld数据目录中。 可以通过刷新日志,来强制mysqld来关闭和重新打开日志文件(或者在某些情况下切换到一个新的日志)。当你执行一个FLUSH LOGS语句或执行mysqladmin flush-logs或mysqladmin refresh时,则日志被老化。对于存在MySQL复制的情形下,从复制服务器将维护更多日志文件,被称为接替日志。

<br>

通用查询日志


在学习通用日志查询时,需要知道几个数据库中的常用命令:

1.show variables like '%version%';

这个命令,可以显示当前数据库中与版本号相关的信息。示例:

mysql> show variables like '%version%';  
+-------------------------+----------------+
| Variable_name           | Value          |
+-------------------------+----------------+
| innodb_version          | 5.7.14         |
| protocol_version        | 10             |
| slave_type_conversions  |                |
| version                 | 10.2.6-MariaDB |
| version_comment         | MariaDB Server |
| version_compile_machine | x86_64         |
| version_compile_os      | Linux          |
| version_malloc_library  | system         |
| version_ssl_library     | YaSSL 2.4.2    |
| wsrep_patch_version     | wsrep_25.19    |
+-------------------------+----------------+
10 rows in set (0.01 sec)

mysql>

以下这个命令是用于查看当前的通用日志查询是否开启,如果general_log的值为ON则为开启,为OFF则为关闭(默认情况下是关闭的)。

2.show variables like '%general%';

示例:

mysql> show variables like '%general%';
+------------------+------------+
| Variable_name    | Value      |
+------------------+------------+
| general_log      | OFF        |
| general_log_file | server.log |
+------------------+------------+
2 rows in set (0.00 sec)

mysql>

以下这个命令是用于查看当前通用查询日志输出的格式,log_output的值可以是FILE(存储在数数据库的数据文件中的hostname.log),也可以是TABLE(存储在数据库中的mysql.general_log)。

3.show variables like '%log_output%';

示例:

mysql> show variables like '%log_output%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | FILE  |
+---------------+-------+
1 row in set (0.00 sec)

mysql> 

<br>

如何开启MySQL通用查询日志,以及使用何种方式去记录这些通用查询日志?
  • 开启通用日志查询: set global general_log=on;

  • 关闭通用日志查询: set global general_log=off;

  • 设置将通用日志记录到数据库表格中: set globallog_output='TABLE';

  • 设置将通用日志记录到本地文件中: set globallog_output='FILE';

  • 设置将通用日志记录到数据库表和本地文件中:set global log_output='FILE,TABLE';

示例:

mysql> set global general_log=on;
Query OK, 0 rows affected (0.01 sec)

mysql> set global log_output='FILE,TABLE';
Query OK, 0 rows affected (0.03 sec)

mysql> select * from mysql.general_log;
+----------------------------+---------------------------+-----------+-----------+--------------+---------------------------------+
| event_time                 | user_host                 | thread_id | server_id | command_type | argument                        |
+----------------------------+---------------------------+-----------+-----------+--------------+---------------------------------+
| 2017-12-10 17:47:35.177238 | root[root] @ localhost [] |       189 |         1 | Query        | select * from mysql.general_log |
| 2017-12-10 17:47:52.608628 | root[root] @ localhost [] |       189 |         1 | Query        | select * from mysql.general_log |
| 2017-12-10 17:47:55.138903 | root[root] @ localhost [] |       189 |         1 | Query        | select * from mysql.general_log |
+----------------------------+---------------------------+-----------+-----------+--------------+---------------------------------+
3 rows in set (0.00 sec)

mysql>

记录到mysql.general_log表中的数据如下:
MySQL慢查询日志

默认情况下记录在本地文件中的通用查询日志文件名称的前缀为主机名,后缀为.log,可以使用find命令寻找,示例:

[root@server ~]# find / -name "server.log"
/data/mariadb/server.log
[root@server ~]# tail /data/mariadb/server.log
Time                 Id Command    Argument
171210 17:46:39   189 Query set global log_output='FILE,TABLE'
171210 17:47:35   189 Query select * from mysql.general_log
171210 17:47:52   189 Query select * from mysql.general_log
171210 17:47:55   189 Query select * from mysql.general_log
171210 17:50:57   189 Quit  
171210 17:52:01   190 Connect   root@localhost as anonymous on 
          190 Query select @@version_comment limit 1
171210 17:52:09   190 Query select * from mysql.general_log
171210 17:52:59   190 Quit  
[root@server ~]#

注意:上述命令只是临时生效,当MySQL重启后则会失效,如果要永久生效,需要配置my.cnf文件

my.cnf文件需要配置的内容如下:

general_log=1   #为1表示开启通用日志查询,值为0表示关闭通用日志查询
log_output=FILE,TABLE   #设置通用日志的输出格式为文件和表

如果没有开启通用日志查询的话,general_log表是空的:

mysql> select * from mysql.general_log;
Empty set (0.00 sec)

mysql>

<br>

慢查询日志


  MySQL的慢查询日志是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的SQL语句,就会被记录到慢查询日志中(日志可以写入文件或者数据库表,如果对性能要求高的话,建议写文件)。所以慢查询日志就是记录mysql服务器中影响数据库性能的相关SQL语句的,通过对这些特殊的SQL语句分析,改进以达到提高数据库性能的目的。默认情况下,MySQL数据库是不开启慢查询日志的,long_query_time的默认值为10(即10秒,通常设置为1秒),即运行10秒以上的语句是慢查询语句。
一般情况下,慢查询发生在数据库比较大的表格中(比如:一个表的数据量有几百万),且查询条件的字段没有建立索引,此时,要匹配查询条件的字段会进行全表扫描,查询耗时超过long_query_time所定义的阈值(预设值),则为慢查询语句,这些慢查询语句就会记录到慢查询日志中。

使用以下命令可以查看当前慢查询日志的开启情况:

show variables like '%quer%';

示例:

mysql> show variables like '%quer%';
+---------------------------------+-----------------+
| Variable_name                   | Value           |
+---------------------------------+-----------------+
| expensive_subquery_limit        | 100             |
| ft_query_expansion_limit        | 20              |
| have_query_cache                | YES             |
| log_queries_not_using_indexes   | OFF             |
| long_query_time                 | 10.000000       |
| query_alloc_block_size          | 16384           |
| query_cache_limit               | 1048576         |
| query_cache_min_res_unit        | 4096            |
| query_cache_size                | 1048576         |
| query_cache_strip_comments      | OFF             |
| query_cache_type                | OFF             |
| query_cache_wlock_invalidate    | OFF             |
| query_prealloc_size             | 24576           |
| slow_query_log                  | OFF             |
| slow_query_log_file             | server-slow.log |
| wsrep_sst_donor_rejects_queries | OFF             |
+---------------------------------+-----------------+
16 rows in set (0.00 sec)

mysql> 

需要关注以下的几个参数:
1.slow_query_log: 的值为ON为开启慢查询日志,OFF则为关闭慢查询日志。

  2.slow_query_log_file: 的值是记录的慢查询日志到文件中(注意:默认名为主机名.log,慢查询日志是否写入指定文件中,需要指定慢查询的输出日志格式为文件,相关命令为:show variables like ‘%log_output%’;去查看输出的格式)。

  3.long_query_time: 指定了慢查询的阈值,即如果执行语句的时间超过该阈值则为慢查询语句,默认值为10秒。

  4.log_queries_not_using_indexes: 如果值设置为ON,则会记录所有没有利用索引的查询(注意:如果只是将log_queries_not_using_indexes设置为ON,而将slow_query_log设置为OFF,此时该设置也不会生效,即该设置生效的前提是slow_query_log的值设置为ON),一般在性能调优的时候会暂时开启。

  5.min_examined_row_limit: 查询检查返回少于该参数指定行的SQL不被记录到慢查询日志

  6.log_slow_queries: 指定是否开启慢查询日志(该参数要被slow_query_log取代,做兼容性保留)

<br>

和通用查询日志一样,慢查询日志也是使用 show variables like '%log_output%'; 语句来查看日志的记录方式:

mysql> show variables like '%log_output%';
+---------------+------------+
| Variable_name | Value      |
+---------------+------------+
| log_output    | FILE,TABLE |
+---------------+------------+
1 row in set (0.00 sec)

mysql>

<br>

设置记录日志的方式也是和之前的一样:

  • 设置将通用日志记录到数据库表格中: set globallog_output='TABLE';

  • 设置将通用日志记录到本地文件中: set globallog_output='FILE';

  • 设置将通用日志记录到数据库表和本地文件中:set global log_output='FILE,TABLE';

<br>

开启慢查询日志:

mysql> set global slow_query_log=on;
Query OK, 0 rows affected (0.00 sec)

mysql> set global long_query_time=1;  # 将阀值设置为1秒
Query OK, 0 rows affected (0.00 sec)

mysql> set session long_query_time=1; # 将session级别的阀值也设置为1秒
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%long_query_time%';  # 查看阀值,默认为10秒
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+
1 row in set (0.00 sec)

mysql> show variables like '%slow_query_log%';  # 查看慢查询日志状态,ON为开启状态,默认为OFF
+---------------------+-----------------+
| Variable_name       | Value           |
+---------------------+-----------------+
| slow_query_log      | ON              |
| slow_query_log_file | server-slow.log |
+---------------------+-----------------+
2 rows in set (0.01 sec)

mysql> show global status like '%slow%';  # 查看慢查询的记录数量
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| Slow_launch_threads | 0     |
| Slow_queries        | 0     |
+---------------------+-------+
2 rows in set (0.06 sec)

mysql> show variables like 'log_queries_not_using_indexes';   # 查看log_queries_not_using_indexes状态
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | OFF   |
+-------------------------------+-------+
1 row in set (0.00 sec)

mysql> 

如果出现修改之后依旧显示为默认值的情况,重新登录mysql就好了,或者在show后面加上global关键字也可以。

<br>

关于慢查询日志的表中的数据个文本中的数据格式分析:

慢查询的日志记录myql.slow_log表中,格式如下:

MySQL慢查询日志

查询语句:

select * from mysql.slow_log;

此时再查看一下慢查询的记录数量:

mysql> show global status like '%slow%';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| Slow_launch_threads | 0     |
| Slow_queries        | 374   |
+---------------------+-------+
2 rows in set (0.00 sec)

mysql>

慢查询日志和通用查询日志都是使用的同一个本地文件:

[root@server ~]# find / -name 'server.log'
/data/mariadb/server.log
[root@server ~]# tail /data/mariadb/server.log
          197 Field List    INNODB_SYS_INDEXES 
          197 Field List    INNODB_SYS_VIRTUAL 
          197 Field List    INNODB_MUTEXES 
          197 Field List    INNODB_SYS_SEMAPHORE_WAITS 
171210 21:43:19   197 Query show tables
171210 21:43:36   197 Query select * from ALL_PLUGINS
171210 21:44:09   197 Query select * from myql.slow_log
171210 21:44:15   197 Query select * from mysql.slow_log
171210 21:44:23   197 Query select * from mysql.slow_log
171210 22:00:12   197 Quit  
[root@server ~]#

可以看到,不管是表还是文件,都具体记录了:是哪条sql语句导致慢查询(sql_text),该慢查询语句的查询时间(query_time),锁表时间(Lock_time),以及扫描过的行数(rows_examined)等信息。

<br>

如何手动产生慢查询语句

实际在学习过程中,如何得知设置的慢查询是有效的?很简单,我们可以手动产生一条慢查询语句,比如,如果我们的慢查询log_query_time的值设置为1,则执行以下这条语句就可以了:

selectsleep(1);

该条语句即是慢查询语句,之后,便可以在相应的日志输出文件或表中去查看是否有该条语句。



本文转自 ZeroOne01 51CTO博客,原文链接:http://blog.51cto.com/zero01/2049236,如需转载请自行联系原作者

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
监控 关系型数据库 MySQL
《MySQL 简易速速上手小册》第7章:MySQL监控和日志分析(2024 最新版)
《MySQL 简易速速上手小册》第7章:MySQL监控和日志分析(2024 最新版)
40 3
|
4天前
|
关系型数据库 MySQL 数据管理
MySQL通过 bin-log 恢复从备份点到灾难点之间数据
MySQL通过 bin-log 恢复从备份点到灾难点之间数据
|
11天前
|
DataWorks 关系型数据库 MySQL
DataWorks产品使用合集之在DataWorks中,如何通过PolarDB for MySQL来查看binlog日志
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
27 1
|
11天前
|
SQL 监控 关系型数据库
【MySQL学习】MySQL的慢查询日志和错误日志
【MySQL学习】MySQL的慢查询日志和错误日志
|
17天前
|
SQL 存储 关系型数据库
MySQL慢日志的介绍以及如何使用问题
MySQL慢日志的介绍以及如何使用问题
17 0
|
1月前
|
存储 SQL 关系型数据库
mysql数据库日志
mysql数据库日志
|
4天前
|
C++
JNI Log 日志输出
JNI Log 日志输出
12 1
|
4天前
|
存储 运维 大数据
聊聊日志硬扫描,阿里 Log Scan 的设计与实践
泛日志(Log/Trace/Metric)是大数据的重要组成,伴随着每一年业务峰值的新脉冲,日志数据量在快速增长。同时,业务数字化运营、软件可观测性等浪潮又在对日志的存储、计算提出更高的要求。
|
10天前
|
XML Java Maven
Springboot整合与使用log4j2日志框架【详解版】
该文介绍了如何在Spring Boot中切换默认的LogBack日志系统至Log4j2。首先,需要在Maven依赖中排除`spring-boot-starter-logging`并引入`spring-boot-starter-log4j2`。其次,创建`log4j2-spring.xml`配置文件放在`src/main/resources`下,配置包括控制台和文件的日志输出、日志格式和文件切分策略。此外,可通过在不同环境的`application.yml`中指定不同的log4j2配置文件。最后,文章提到通过示例代码解释了日志格式中的各种占位符含义。
|
10天前
|
运维 监控 Go
Golang深入浅出之-Go语言中的日志记录:log与logrus库
【4月更文挑战第27天】本文比较了Go语言中标准库`log`与第三方库`logrus`的日志功能。`log`简单但不支持日志级别配置和多样化格式,而`logrus`提供更丰富的功能,如日志级别控制、自定义格式和钩子。文章指出了使用`logrus`时可能遇到的问题,如全局logger滥用、日志级别设置不当和过度依赖字段,并给出了避免错误的建议,强调理解日志级别、合理利用结构化日志、模块化日志管理和定期审查日志配置的重要性。通过这些实践,开发者能提高应用监控和故障排查能力。
87 1