监控
我们可以使用 Slow_queries 状态变量监视由于花费的时间超过 long_query_time 秒而记录为慢查询的查询数量,例如:
mysql> SHOW GLOBAL STATUS LIKE 'Slow_queries'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Slow_queries | 8 | +---------------+-------+ 1 row in set (0.00 sec)
我们还可以使用 MySQL Enterprise Monitor (MEM) 中的慢查询图来监控此状态变量。
MySQL Enterprise Monitor 还允许我们使用查询分析器 (QUAN) 记录慢查询。
启用和禁用慢查询日志
如何启用和禁用慢查询日志取决于我们使用的 MySQL 版本。
5.1 及更高版本
在 MySQl 5.1 及更高版本中,我们可以使用 slow_query_log 选项启用和禁用慢查询日志。
我们可以像这样动态设置此变量:
SET GLOBAL slow_query_log = OFF;
该变量只能全局设置,因此会影响所有连接。
5.0 及更早版本
如果我们使用 MySQL 5.0 或者更早版本,则必须在 MySQL 配置文件中设置 log_slow_queries 选项。
我们可以选择指定将慢查询记录到的文件(默认为数据目录中的 host_name-slow.log),例如:
[mysqld] log_slow_queries
它需要在更改生效之前重新启动 MySQL。
mysqldumpslow
为了帮助分析慢查询日志,MySQL 附带了 mysqldumpslow 脚本。
慢查询日志记录所有满足慢查询日志设置指定条件的查询。
但是为了确定哪些查询最需要关注,总结慢查询日志是一个优势;例如,每秒执行数百次的查询可能比每天只执行一次的查询更重要,即使后者需要更长的时间。
通过为慢查询日志中出现的每个查询创建聚合统计信息,我们可以获得查询在慢查询日志中出现的频率、平均查询时间是多少等的概述。
mysqldumpslow 脚本可以提供这些类型的摘要。
如何设置mysql的日志的存储位置和记录的内容
5.1 及更高版本
我们可以使用以下选项控制日志的目的地:
slow_query_log_file:将此选项设置为日志文件的文件名。
日志文件为纯文本格式,我们可以使用 mysqldumpslow 脚本(见下文)生成摘要。
- log_output:此选项控制是否记录到表和/或者文件(另请参阅上面的 slow_query_log_file 选项)。
当我们选择记录到某个表时,可以在表 mysql.slow_log 中找到慢查询日志。
我们可以动态更改该值,并且可以指定单个值或者逗号分隔的值列表,例如:
SET GLOBAL log_output = 'TABLE,FILE';
允许的值有:
- NONE
- FILE
- TABLE
- TABLE,FILE
了解适用于 mysql.slow_log 表的限制很重要。
一些限制是:
- CREATE TABLE 、 ALTER TABLE 和 DROP TABLE 是对日志表的有效操作。对于 ALTER TABLE 和 DROP TABLE,日志表不能在使用中,必须禁用,如下所述。
- INSERT 、 DELETE 和 UPDATE 不能用于日志表。这些操作仅在服务器本身内部允许。
例如,如果我们尝试重新加载 slow_log 表,因为我们必须显式禁用常规查询日志和慢速查询日志才能删除(包括删除 mysql 数据库)和/或者创建表,这些限制会产生影响,并且我们必须确保在重新加载时不要尝试将行插入表中。
5.0 及更早版本
在 MySQL 5.0 及更早版本中,我们可以通过为 log_slow_queries 选项指定文件名来指定慢查询日志的目的地,例如:
[mysqld] log_slow_queries = /var/log/mysql/slow_queries.log
无法动态更改目标,因此在更改生效之前需要重新启动 MySQL。
控制时间戳时区
在 MySQL 5.7.2 及更高版本中,可以使用 log_timestamps 选项控制用于慢查询日志中时间戳的时区。
它只影响写入基于文件的日志的查询。
允许的值为:
- 世界标准时间
- 系统
5.7.2 及更高版本中的默认值是 UTC 。
在早期版本中,时间戳使用系统时区。
该选项还控制用于一般查询日志中时间戳的时区。
控制记录的内容
MySQL 有几个选项来控制慢查询日志中包含的内容。
服务器按照以下顺序使用控制参数来确定是否将查询写入慢查询日志:
- 查询不能由 SQL 从属线程执行,或者必须启用 log-slow-slave-statements。
- 查询必须不是管理语句,或者必须启用 log-slow-admin-statements。
- 查询必须至少花费了 long_query_time 秒,或者必须启用 log_queries_not_using_indexes 并且查询不使用任何索引进行行查找。
- 查询必须至少检查过 min_examined_row_limit 行。
下面将详细讨论这些选项。
long_query_time
long_query_time 变量以秒为单位指定阈值。
如果查询花费的时间比这更长,则将记录该查询。
该变量可以在会话级别设置,例如,如果我们事先知道查询将需要很长时间,我们可以适当地设置阈值以避免记录我们已经知道的查询不能更快。
同样,如果我们在应用程序中必须快速的部分,则可以降低阈值。
在 MySQL 5.1.21 和 5.5 及更高版本中,我们可以指定值 0 来记录所有查询,并且支持微秒分辨率。
在早期版本中,最小值为 1,并且仅支持整数。
log_queries_not_using_indexes
将 log_queries_not_using_indexes 设置为 ON 时,将记录所有执行全表或者索引扫描的查询。
启用此选项后,将 long_query_time 设置得非常高通常是有好处的,这样只会记录不使用索引的查询。
log_throttle_queries_not_using_indexes
当启用 log_queries_not_using_indexes 选项时,记录到慢查询日志的查询数量可能过多。
log_throttle_queries_not_using_indexes 选项可用于通过设置每分钟的最大查询数来限制不使用索引的查询。
默认值为 0,表示不节流。
该选项在 5.6.5/5.7 及更高版本中可用。
min_examined_row_limit
min_examined_row_limit 是在将查询记录到慢查询日志之前要检查的最小行数。
将此设置与 log_queries_not_using_indexes 一起使用可以防止对非常小的表进行日志记录查询,在这些表中扫描所有行都无关紧要。
log_slow_admin_statements
log_slow_admin_statements 控制诸如 OPTIMIZE TABLE、ANALYZE TABLE 和 ALTER TABLE 之类的管理语句是否会记录在慢查询日志中。
在 MySQL 5.6.10/5.5 及更早版本中,这只能在 MySQL 配置文件中设置,并且需要重新启动才能生效。
在 5.6.11/5.7 及更高版本中,该选项可以动态设置。
log_slow_slave_statements
通过从属服务器执行的默认查询,线程将不会被记录。
要启用记录从属更新,请使用 log_slow_slave_statements 选项。
在 MySQL 5.6.10/5.5 及更早版本中,这只能在 MySQL 配置文件中设置,并且需要重新启动才能生效。
在 5.6.11/5.7 及更高版本中,该选项可以动态设置。
顾名思义,慢查询日志记录需要很长时间执行或者未使用索引的查询,这可能比所需的慢。
以下一般属性适用于慢查询日志:
- 查询时间是从获得任何初始表锁之后开始测量的。
- 释放所有锁后,查询将写入慢查询日志。这减少了持有锁的时间,但意味着需要相同表锁的两个查询可能会以相反的顺序在慢查询日志中结束。
- 为查询测量的执行时间是执行查询所需的实时时间(挂钟时间)。因此,如果系统负载很重,只需要一点 CPU 时间的查询仍然会出现在慢查询日志中。