目前在生产环境的MySQL的主流版本有5.5, 5.6, 5.7三个版本,其中阿里云,腾讯云等主要使用的是5.6的版本(双机高可用), 5.7的版本还在测试跟进中,还未在云上大规模的使用。
这些主流的版本都已经原生支持「慢日志」功能,只需要开启并使用慢日志分析工具,即可找出慢查询语句。相应的云平台也提供了慢日志的管理界面,不过也是在原生Mysql的慢日志功能的包装和增强。
在这之前,我们先看看关于慢查询几个重要的参数:
开启慢日志功能
有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秒即为慢查询
没有配置日志文件路径和名称,就使用默认的。
重启msyqld服务就可以生效,登入msyql,查看生效情况
SHOW VARIABLES WHERE Variable_name IN('slow_query_log','long_query_time','slow_query_log_file','log-query-not-using-indexes');
可以看到重启后,日志生效。
2、二是通过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,我们可以自定义路径和文件名
可以立即生效,但是msyqld重启以后会失效,因为msyql重启的时候,是按照配置文件来加载配置的,set global语句,只对当前所有会话生效,并未修改配置文件。
慢日志除了记录到文件,还可以记录到数据库表中。只要将mysql全局变量log_output设置为 TABLE即可。MySQL会将日志分别记录到表mysql.gengera_log和mysql.slow_log二张表中。但是,我们推荐将日志记录 在日记文件中,记录到文件可以支持微秒,记录到到数据库表中并不支持。
验证:
在测试的时候,即便有几十万的记录,一条语句很可能零点几秒就执行完了。好在Mysql提供了一个SLEEP函数,可以延迟返回查询结果,比如:
现在去查看日志
可以看到刚才的慢查询记录。
当然随着时间积累,慢日志文件会原来越大,使用cat,grep等命令分析会很困难。Mysql自带mysqldumpslow的可以用做分析,当然还有一个第三方开源的工具,比如mk-query-digest,mysqlsla,myprofi
下面是网上总结的几个工具
mysqldumpslow支持不支持perlmysql官方自带
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缓存的没有用上;数据库字段类型设计不合理,等等,需要细处着手,全盘考虑。
具体参数可参考MySQL官方链接:
https://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html