pupuk / mysql

Questions & Thinking

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MySQL开启慢日志- Enable MySQL slow query log

pupuk opened this issue · comments

主要参数

目前在生产环境的MySQL的主流版本有5.5, 5.6 ,5.7三个版本,其中阿里云,腾讯云等主要使用的是5.6的版本(双机高可用), 5.7的版本还在测试跟进中,还未在云上大规模的使用。
这些主流的版本都已经原生支持「慢日志」功能,只需要开启并使用日志分析工具即可,云平台也提供了慢日志的管理界面,不过也是在原生MySQL的慢日志功能的包装和增强。

在这之前,我们先看看关于满查询几个重要的参数:

参数 说明
slow_query_log 是否开启慢查询日志 {0|1} --defaul 0, OFF
long_query_time 多少时间算慢查询 最小值为0,默认值是10s
记录到文件,支持到微秒
记录到数据表,支持到秒
slow_query_log_file 日志记录的文件 /var/lib/mysql/hostname-slow.log
默认以hostname为名,放在msyql的data
log-query-not-using-indexes 记录没使用索引的查询语句 ON|OFF

开启慢日志功能

有2种方式,一是修改mysql的配置文件,二是通过set global语句来实现。

  1. 修改配置文件,Windows 的配置文件为 my.ini,一般在 MySQL 的安装目录下。linux 的配置文件为my.cnf ,一般在/etc目录下。
    在linux下,vim /etc/my.cnf,在[mysqld]内容项下增加
slow_query_log = ON
long_query_time = 2

我这里设置慢查询时间long_query_time 设置的是2s,认为超过2秒即为慢查询
没有配置日志文件路径和名称,就使用默认的。
image1

重启mysqld服务就可以生效,登入MySQL,查看生效情况。

SHOW VARIABLES WHERE Variable_name IN('slow_query_log','long_query_time','slow_query_log_file','log-query-not-using-indexes');

image2
image3

可以看到重启后,日志生效。

  1. 二是通过set global语句来实现,可以在mysql -uroot -p登录后,输入:
    SET GLOBAL slow_query_log = 'ON';
    就可以立即开始慢日志记录,如果想指定时间和文件位置,可以追加配置:
    SET GLOBAL long_query_time = X;
    X默认是10s,也就是说超过10s的查询会被记入慢日志。

SET GLOBAL slow_query_log_file = '/path/filename';
日志路径默认是:/var/lib/mysql/hostname-slow.log 文件名中默认包含了当前服务器的hostname,我们可以自定义路径和文件名

可以立即生效,但是mysqld重启以后会失效,因为mysql重启的时候,是按照配置文件来加载配置的,set global语句,只对当前所有会话生效,并未修改配置文件

好在MySQL8.0以后,增加了参数持久化功能,可以通过
SET PERSIST 语句将参数设置到global会话,并保证在下次重启MySQL的时候,参数依然有效。
具体可以看相关文档:
MySQL8.0 官方文档:System Variable Assignment

慢日志除了记录到文件,还可以记录到数据库表中。只要将mysql全局变量log_output设置为 TABLE即可。MySQL会将日志分别记录到表mysql.gengera_logmysql.slow_log二张表中。但是,我们推荐将日志记录 在日记文件中,记录到文件可以支持微秒,记录到到数据库表中并不支持。

验证:

在测试的时候,即便有几十万的记录,一条语句很可能零点几秒就执行完了。还在Mysql提供了一个SLEEP函数,可以延迟返回查询结果,比如:
image4
现在去查看日志
image5
可以看到刚才的慢查询记录。

当然随着时间积累,慢日志文件会原来越大,使用catgrep等命令分析会很困难。MySQL自带mysqldumpslow的可以用做分析,当然还有一个第三方开源的工具,比如mk-query-digestmysqlslamyprofi
下面是网上总结的几个工具:

工具 特性 不支持 语言 说明
mysqldumpslow 支持 不支持 perl mysql官方自带
mysqlsla 支持 支持 perl 功能强大,数据报表齐全,定制化能力强.
mysql-explain-slow-log 支持 不支持 perl
mysql-log-filter 支持 部分支持 python or php 不失功能的前提下,保持输出简洁
myprofi 支持 不支持 php 非常精简

可能值得我们注意的地方有:

  1. 初始化锁的时间不算在执行时间内。Mysqld服务写慢日志,是在sql语句执行完,并且所有的锁释放之后才进行的,所以日志顺序和执行顺序有所不同。
  2. 如果是主从架构(Master,Slave),默认从库不会记录相同的慢日志。如果要修改,可以用log_slow_slave_statements来设置

找出慢日志,可以有效的帮我们我们优化MySQL语句,当然不是简单的加个索引的事情,可能涉及一些不合理的设计,比如该应用层的操作,让sql来做了;该做中间统计表的没有做,每次都是大表实时汇总,该用redis缓存的没有用上,数据库字段类型设计不合理,等等,需要全盘考虑。

官方文档

https://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html