MySQL Slow Query Log

2024 年 8 月 29 日 | 阅读 6 分钟

什么是慢查询日志?

慢查询日志是数据库性能优化中的复杂组件之一。它捕获执行时间超过指定时长(由 'long_query_time' 定义)的 SQL 语句。它也基于 'min_examined_row_limit' 工作。数据库管理员可以使用 'mysqldumpslow' 命令来发现瓶颈,这对于监控长时间、缓慢的查询日志很有帮助。

如何启用慢查询日志?

慢查询会影响数据库乃至整个服务器的性能。您可以使用慢查询日志功能在 MySQL 中记录执行时间超过预定时间的查询。这使得识别耗时或低效的查询变得容易得多。

使用以下方法启用慢查询。

  • 第一步: 首先,登录到您的服务器。
  • 第二步: 在命令行中输入以下命令。
    • 第三步: 然后,输入 MySQL Root 密码。
    • 第四步: 在 mysql> 提示符下输入以下命令以启用慢查询日志。
    • 第五步: 慢查询日志功能会自动记录耗时超过 10 秒的查询,可以通过使用命令 X 更改间隔来调整此时间。
    • 默认的慢查询日志文件位于 /var/lib/mysql/hostname-slow.log。使用以下命令修改日志路径或文件名。
    • 第六步: 为确保慢查询日志正常工作,退出并重新进入 MySQL 软件,重新加载会话变量,并将 X 更改为比 long_query_time 参数更大的数字。
    • 第七步: 监控慢查询日志文件,以找出哪些查询执行时间过长。
    • 第八步: 完成调试后,关闭慢查询日志。为此,再次启动 MySQL 软件,然后输入以下命令。

    慢查询参数和内容是什么?

    慢查询参数

    对于长查询时间,最小值和默认值分别为 0 和 10。您可以将该值指定到微秒级的精度。

    • 默认情况下,不记录不需要索引查找的查询类型,也不记录管理语句。稍后将讨论,可以使用 log_slow_admin_statements 和 log_queries_not_using_indexes 来修改此行为。
    • 慢查询日志默认是禁用的,但可以使用命令 --slow_query_log[={0|1}] 设置为 0 或 1,并使用 log_output 系统变量指定日志文件名。
    • 服务器默认慢查询日志文件名为 host_name-slow.log,除非提供了绝对路径名,否则文件创建在数据目录中。
    • 使用全局系统变量 slow_query_log 和 slow_query_log_file 可以在运行时启用或禁用慢查询日志并修改其文件名。要定义日志文件名,请设置 slow_query_log_file。新文件将被打开,任何已打开的日志文件都将被关闭。
    • 如果您设置了 --log-short-format 选项,服务器将向慢查询日志写入较少的数据。
    • 启用 log_slow_admin_statements 系统变量,将慢管理语句添加到查询日志中,包括 alter table, analyze table, check table, create index, drop index, optimize table, 和 repair table。
    • 启用 log_queries_not_using_indexes 系统变量,将未使用索引进行行查找的查询包含在慢查询日志语句中。此设置可防止服务器记录少于两行的搜索,因为在这种情况下索引没有用处。
    • 当记录没有索引的请求时,慢查询日志可能会变得非常大。通过修改 log_throttle_queries_not_using_indexes 系统变量,可以对此类查询施加速率限制。由于此变量默认值为 0,因此没有限制。正数值设置了每分钟可以记录的未使用索引的查询数量的限制。
      在接收到此类查询后的前 60 秒内,服务器会记录达到指定限制的查询,之后会抑制进一步的搜索。当时间窗口关闭时,服务器会记录一个摘要,指示被抑制的查询数量以及在这些查询上花费的总时间。当服务器记录下一个符合条件的查询时,下一个 60 秒窗口开始。
    • 在决定是否将查询提交到慢查询日志时,服务器会按顺序考虑以下控制参数:
      1. 必须启用 log_slow_admin_statements,或者查询不能是管理语句。
      2. 查询必须至少耗时 long_query_time 秒,或者必须启用 log_queries_not_using_indexes 并且查询未使用索引进行行查找。
      3. 查询必须至少检查了 min_examined_row_limit 行。
      4. 根据 log_throttle_queries_not_using_indexes 选项,查询不能被静默处理。
    • log_timestamps 系统变量控制发送到慢查询日志文件、通用查询日志文件和错误日志的消息中时间戳的时区。它不影响写入日志表的通用查询日志和慢查询日志消息的时区;但是,可以使用 CONVERT_TZ() 或通过将会话的 time_zone 系统变量从本地系统时区更改为任何所需时区来转换从这些表中接收的行。
    • 副本服务器不会自动将复制的查询写入慢查询日志。您可以通过设置 log_slow_slave_statements(MySQL 8.0.26 之前)或 log_slow_replica_statements(从 MySQL 8.0.26 开始)系统变量来修改此行为。需要注意的是,如果启用了基于行的复制(binlog_format=ROW),这些系统变量将不起作用。
      只有当查询以语句格式记录在二进制日志中时,副本的慢查询日志才会被包含,即当设置了 binlog_format=STATEMENT 或 binlog_format=MIXED 时,或者当设置了 binlog_format=MIXED 或 binlog_format=ROW 时,慢查询以行格式记录。

    慢查询日志内容

    • 当启用慢查询日志时,服务器会将输出写入指定的目标,激活时会打开日志文件并写入启动消息。但除非选择了 FILE 日志目标,否则不会有更多查询记录到文件中。即使启用了慢查询日志,如果目标是 NONE,服务器也不会写入任何查询。如果未选择 FILE 作为输出目标,更改日志文件名不会影响日志记录。
    • 如果启用了慢查询日志并且选择了 FILE 作为输出目标,则日志中的每个语句都在单行中包含指定的字段。
      • Query_time: duration
        上述语句以秒为单位执行。
      • Lock_time: duration
        这用于获取锁,单位为秒。
      • Rows_sent: N
        这表示锁定的行数,单位为秒。
      • Rows_examined
        服务器层检查的行数。
    • 当启用 log_slow_extra 系统变量(自 MySQL 8.0.14 起可用)时,除了前面提到的字段外,服务器还会将下面描述的附加字段写入 FILE 输出(TABLE 输出不受影响)。一些字段描述使用了状态变量的名称。有关更多详细信息,请参阅状态变量的解释。然而,慢查询日志中的计数器是每个语句的数据,而不是每个会话的累积值。
    • 启用 log_slow_extra 可能会导致慢查询日志文件中混合包含带有和不带附加信息的行。日志文件分析器可以通过计算字段来判断一行上是否有更多字段。
    • 每个写入慢查询日志文件的语句前面都有一个带有时间戳的 SET 语句。从 MySQL 8.0.14 开始,时间戳显示慢语句执行的开始时间。在 8.0.14 版本之前,时间戳记录的是慢语句被报告的时刻(这发生在语句执行完成之后)。
    • 为了防止密码以明文形式出现,服务器会重写发布到慢查询日志中的语句中的密码。