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语句来实现。
- 修改配置文件,
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秒即为慢查询
没有配置日志文件路径和名称,就使用默认的。
重启mysqld服务就可以生效,登入MySQL,查看生效情况。
SHOW VARIABLES WHERE Variable_name IN('slow_query_log','long_query_time','slow_query_log_file','log-query-not-using-indexes');
可以看到重启后,日志生效。
- 二是通过
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_log
和mysql.slow_log
二张表中。但是,我们推荐将日志记录 在日记文件中,记录到文件可以支持微秒,记录到到数据库表中并不支持。
验证:
在测试的时候,即便有几十万的记录,一条语句很可能零点几秒就执行完了。还在Mysql提供了一个SLEEP
函数,可以延迟返回查询结果,比如:
现在去查看日志
可以看到刚才的慢查询记录。
当然随着时间积累,慢日志文件会原来越大,使用cat
,grep
等命令分析会很困难。MySQL自带mysqldumpslow
的可以用做分析,当然还有一个第三方开源的工具,比如mk-query-digest
,mysqlsla
,myprofi
下面是网上总结的几个工具:
工具 | 特性 | 不支持 | 语言 | 说明 |
---|---|---|---|---|
mysqldumpslow | 支持 | 不支持 | perl | mysql官方自带 |
mysqlsla | 支持 | 支持 | perl | 功能强大,数据报表齐全,定制化能力强. |
mysql-explain-slow-log | 支持 | 不支持 | perl | 无 |
mysql-log-filter | 支持 | 部分支持 | python or php | 不失功能的前提下,保持输出简洁 |
myprofi | 支持 | 不支持 | php | 非常精简 |
可能值得我们注意的地方有:
- 初始化锁的时间不算在执行时间内。Mysqld服务写慢日志,是在sql语句执行完,并且所有的锁释放之后才进行的,所以日志顺序和执行顺序有所不同。
- 如果是主从架构(Master,Slave),默认从库不会记录相同的慢日志。如果要修改,可以用
log_slow_slave_statements
来设置
找出慢日志,可以有效的帮我们我们优化MySQL语句,当然不是简单的加个索引的事情,可能涉及一些不合理的设计,比如该应用层的操作,让sql来做了;该做中间统计表的没有做,每次都是大表实时汇总,该用redis缓存的没有用上,数据库字段类型设计不合理,等等,需要全盘考虑。