最佳实践

 

使用 percona-toolkit 工具分析 MySQL 慢日志

更新时间 2023-09-06

默认总耗时时长超过 3s 的语句会被记录到慢日志中。时长可通过参数 Long_query_time 进行调整,参数详细介绍及修改参数的步骤请参见参数介绍修改配置参数

本小节主要介绍如何通过 percona-toolkit 工具进行 MySQL 慢日志分析。

步骤一:安装 percona-toolkit 工具集

需要准备一台 Linux 云服务器,用于安装 percona-toolkit 工具集。

  1. 准备一台 Linux 云服务器。

    说明

    建议Linux 云服务器与 MySQL PLus 集群部署在同一 VPC 下。若 Linux 云服务器与 MySQL PLus 网络不通,可通过边界路由器VPN 等方式打通网络。

  2. 登录 Linux 云服务器。

  3. 执行以下命令,下载 percona-toolkit 工具集。

    wget https://downloads.percona.com/downloads/percona-toolkit/3.5.0/binary/tarball/percona-toolkit-3.5.0_x86_64.tar.gz
    
  4. 执行以下命令,解压安装包。

    tar -zxvf ./percona-toolkit-3.5.0_x86_64.tar.gz
    
  5. 安装包解压后即可使用 percona-toolkit 工具。

    • 工具集路径:./percona-toolkit-3.5.0/bin/。
    • 慢日志统计工具路径:./percona-toolkit-3.5.0/bin/pt-query-digest。

步骤二:获取慢日志

详细操作请参见下载 MySQL 日志

步骤三:分析慢日志

  1. 将获取到的慢日志传到 percona-toolkit 工具集所在的 Linux 云服务器上。

    假如慢日志在 Linux 云服务器上的保存路径为:/data/mysql-log/mysql-slow/mysql-slow.log。

  2. 登录 Linux 云服务器。

  3. 执行以下命令,分析 mysql-slow.log 中的相关慢日志,并输出分析结果(本文以输出到文本文件 A.txt 为例)。

    /home/ubuntu/percona-toolkit-3.5.0/bin/pt-query-digest /data/mysql-log/mysql-slow/mysql-slow.log > /data/A.txt
    

    参数说明

    • /home/ubuntu/percona-toolkit-3.5.0/bin/pt-query-digest:慢日志统计工具路径。
    • /data/mysql-log/mysql-slow/mysql-slow.log:慢日志保存路径。
    • A.txt:分析结果的文本文件名称,可以自定义。

分析结果示例

打开 A.txt 文件,即可看到慢日志分析结果。

# 200ms user time, 10ms system time, 29.74M rss, 36.67M vsz
# Current date: Thu Dec 29 15:49:04 2022
# Hostname: i-6emrs19i
# Files: /data/mysql-log/mysql-slow/mysql-slow.log
# Overall: 8 total, 2 unique, 0.00 QPS, 0.03x concurrency ________________
# Time range: 2022-12-29T14:16:26 to 2022-12-29T15:38:52
# Attribute          total     min     max     avg     95%  stddev  median
# ============     ======= ======= ======= ======= ======= ======= =======
# Exec time           158s      3s     51s     20s     49s     15s     20s
# Lock time            2ms   148us     1ms   306us     1ms   276us   224us
# Rows sent              0       0       0       0       0       0       0
# Rows examine      33.50M   1.00M   8.00M   4.19M   7.65M   2.54M   4.93M
# Rows affecte      20.75M 512.00k   8.00M   2.59M   7.65M   2.22M   2.42M
# Bytes sent           446      14      62   55.75   59.77   15.19   59.77
# Query size           407      22      55   50.88   54.21   10.83   54.21

# Profile
# Rank Query ID                           Response time  Calls R/Call  V/M
# ==== ================================== ============== ===== ======= ===
#    1 0x1F32B88358F38D34F85C6FAE9E2CE01A 106.5287 67.5%     7 15.2184  7.13 INSERT SELECT apple_test
#    2 0xCED5D8C62622BEA1DE7AD589E9A48AA9  51.2485 32.5%     1 51.2485  0.00 DELETE apple_test

# Query 1: 0.00 QPS, 0.02x concurrency, ID 0x1F32B88358F38D34F85C6FAE9E2CE01A at byte 3850
# This item is included in the report because it matches --limit.
# Scores: V/M = 7.13
# Time range: 2022-12-29T14:16:26 to 2022-12-29T15:38:52
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         87       7
# Exec time     67    107s      3s     36s     15s     35s     10s     11s
# Lock time     57     1ms   148us   315us   202us   301us    52us   159us
# Rows sent      0       0       0       0       0       0       0       0
# Rows examine  76  25.50M   1.00M   8.00M   3.64M   7.65M   2.29M   2.88M
# Rows affecte  61  12.75M 512.00k   4.00M   1.82M   3.86M   1.14M   1.46M
# Bytes sent    96     432      61      62   61.71   59.77       0   59.77
# Query size    94     385      55      55      55      55       0      55
# String:
# Databases    testdb
# Hosts        localhost
# Last errno   0
# Users        root
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms
#    1s  ################################################
#  10s+  ################################################################
# Tables
#    SHOW TABLE STATUS FROM `testdb` LIKE 'apple_test'\G
#    SHOW CREATE TABLE `testdb`.`apple_test`\G
insert into apple_test(a, b) select a,b from apple_test\G

# Query 2: 0 QPS, 0x concurrency, ID 0xCED5D8C62622BEA1DE7AD589E9A48AA9 at byte 4190
# This item is included in the report because it matches --limit.
# Scores: V/M = 0.00
# Time range: all events occurred at 2022-12-29T15:28:18
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count         12       1
# Exec time     32     51s     51s     51s     51s     51s       0     51s
# Lock time     42     1ms     1ms     1ms     1ms     1ms       0     1ms
# Rows sent      0       0       0       0       0       0       0       0
# Rows examine  23   8.00M   8.00M   8.00M   8.00M   8.00M       0   8.00M
# Rows affecte  38   8.00M   8.00M   8.00M   8.00M   8.00M       0   8.00M
# Bytes sent     3      14      14      14      14      14       0      14
# Query size     5      22      22      22      22      22       0      22
# String:
# Databases    testdb
# Hosts        localhost
# Last errno   0
# Users        root
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms
#    1s
#  10s+  ################################################################
# Tables
#    SHOW TABLE STATUS FROM `testdb` LIKE 'apple_test'\G
#    SHOW CREATE TABLE `testdb`.`apple_test`\G
delete from apple_test\G
# Converted for EXPLAIN
# EXPLAIN /*!50100 PARTITIONS*/
select * from  apple_test\G

分析结果说明

结果示例中有两类耗时较长的语句,如下:

insert into apple_test(a, b) select a,b from apple_test; 
delete from apple_test;

可将结果分为三部分:

  • 第一部分:总体概要信息

    # 200ms user time, 10ms system time, 29.74M rss, 36.67M vsz
    # Current date: Thu Dec 29 15:49:04 2022
    # Hostname: i-6emrs19i
    # Files: /data/mysql-log/mysql-slow/mysql-slow.log
    # Overall: 8 total, 2 unique, 0.00 QPS, 0.03x concurrency ________________
    # Time range: 2022-12-29T14:16:26 to 2022-12-29T15:38:52
    # Attribute          total     min     max     avg     95%  stddev  median
    # ============     ======= ======= ======= ======= ======= ======= =======
    # Exec time           158s      3s     51s     20s     49s     15s     20s
    # Lock time            2ms   148us     1ms   306us     1ms   276us   224us
    # Rows sent              0       0       0       0       0       0       0
    # Rows examine      33.50M   1.00M   8.00M   4.19M   7.65M   2.54M   4.93M
    # Rows affecte      20.75M 512.00k   8.00M   2.59M   7.65M   2.22M   2.42M
    # Bytes sent           446      14      62   55.75   59.77   15.19   59.77
    # Query size           407      22      55   50.88   54.21   10.83   54.21
    

    参数说明如下:

    参数名称 参数说明
    Current date 分析结果生成的时间。
    Hostname 主机名。
    Files 分析的文件所在路径。
    Overall 分析的 SQL 数量统计。
    本示例中总共存在的慢 SQL 有 8 条,实际上分为两类,insert 和 delete。
  • total 为总语句数量。
  • unique 为唯一查询数量,即对查询条件进行参数化以后,统计的总共有多少个不同的查询。
  • Time range 本次分析中所以慢 SQL 所在的时间段。
    Exec time SQL 执行时间。
  • total 总时间。
  • min 最短时间。
  • max 最长时间。
  • avg 平均时间。
  • 95% 把所有耗时从小到大排列,位置最接近 95% 的那个数。
  • stddev 标准偏差。
  • median 中位数。
  • Lock time 锁占用的时间。
    Row sent 发送到客户端的行数。
    Row examine SQL 语句扫描行数。
    Bytes sent 发送到客户端的字节数。
    Query size 查询的字符数。
  • 第二部分:SQL 概要信息

    # Profile
    # Rank Query ID                           Response time  Calls R/Call  V/M
    # ==== ================================== ============== ===== ======= ===
    #    1 0x1F32B88358F38D34F85C6FAE9E2CE01A 106.5287 67.5%     7 15.2184  7.13 INSERT SELECT apple_test
    #    2 0xCED5D8C62622BEA1DE7AD589E9A48AA9  51.2485 32.5%     1 51.2485  0.00 DELETE apple_test
    

    参数说明如下:

    参数名称 参数说明
    Rank SQL 在此次统计中的耗时排名。
    Query ID pt-query-digest 为此类 SQL 生成的唯一 ID,可以通过此 ID 找到本 SQL 对应的详细信息。
    Response time 此类 SQL 总耗时时间。全部 Query 加起来就是所有慢 SQL 的总耗时时间。
    百分比数值是该类 SQL 耗时占此次统计慢 SQL 总耗时时间的百分比。全部 Query 加起来就是 100%。
    calls 执行次数,即本次分析总共有多少条这种类型的 SQL 语句。
    R/Call 平均每次执行的响应时间。
    V/M 响应时间的方差与平均比。
    - 大致的 SQL 语句,体现 SQL 的类型。
  • 第三部分:SQL 详细信息

    # Query 1: 0.00 QPS, 0.02x concurrency, ID 0x1F32B88358F38D34F85C6FAE9E2CE01A at byte 3850
    # This item is included in the report because it matches --limit.
    # Scores: V/M = 7.13
    # Time range: 2022-12-29T14:16:26 to 2022-12-29T15:38:52
    # Attribute    pct   total     min     max     avg     95%  stddev  median
    # ============ === ======= ======= ======= ======= ======= ======= =======
    # Count         87       7
    # Exec time     67    107s      3s     36s     15s     35s     10s     11s
    # Lock time     57     1ms   148us   315us   202us   301us    52us   159us
    # Rows sent      0       0       0       0       0       0       0       0
    # Rows examine  76  25.50M   1.00M   8.00M   3.64M   7.65M   2.29M   2.88M
    # Rows affecte  61  12.75M 512.00k   4.00M   1.82M   3.86M   1.14M   1.46M
    # Bytes sent    96     432      61      62   61.71   59.77       0   59.77
    # Query size    94     385      55      55      55      55       0      55
    # String:
    # Databases    testdb
    # Hosts        localhost
    # Last errno   0
    # Users        root
    # Query_time distribution
    #   1us
    #  10us
    # 100us
    #   1ms
    #  10ms
    # 100ms
    #    1s  ################################################
    #  10s+  ################################################################
    # Tables
    #    SHOW TABLE STATUS FROM `testdb` LIKE 'apple_test'\G
    #    SHOW CREATE TABLE `testdb`.`apple_test`\G
    insert into apple_test(a, b) select a,b from apple_test\G
    
    # Query 2: 0 QPS, 0x concurrency, ID 0xCED5D8C62622BEA1DE7AD589E9A48AA9 at byte 4190
    # This item is included in the report because it matches --limit.
    # Scores: V/M = 0.00
    # Time range: all events occurred at 2022-12-29T15:28:18
    # Attribute    pct   total     min     max     avg     95%  stddev  median
    # ============ === ======= ======= ======= ======= ======= ======= =======
    # Count         12       1
    # Exec time     32     51s     51s     51s     51s     51s       0     51s
    # Lock time     42     1ms     1ms     1ms     1ms     1ms       0     1ms
    # Rows sent      0       0       0       0       0       0       0       0
    # Rows examine  23   8.00M   8.00M   8.00M   8.00M   8.00M       0   8.00M
    # Rows affecte  38   8.00M   8.00M   8.00M   8.00M   8.00M       0   8.00M
    # Bytes sent     3      14      14      14      14      14       0      14
    # Query size     5      22      22      22      22      22       0      22
    # String:
    # Databases    testdb
    # Hosts        localhost
    # Last errno   0
    # Users        root
    # Query_time distribution
    #   1us
    #  10us
    # 100us
    #   1ms
    #  10ms
    # 100ms
    #    1s
    #  10s+  ################################################################
    # Tables
    #    SHOW TABLE STATUS FROM `testdb` LIKE 'apple_test'\G
    #    SHOW CREATE TABLE `testdb`.`apple_test`\G
    delete from apple_test\G
    # Converted for EXPLAIN
    # EXPLAIN /*!50100 PARTITIONS*/
    select * from  apple_test\G
    
    • Query 1、Query 2 是此次分析结果中出现的两类慢 SQL。

    • 参数说明:
      列表参数可以参考第一部分,其他参数说明如下:

      参数名称 参数说明
      Databases SQL 执行的数据库。
      Users SQL 执行的用户。
      Query_time distribution 查询时长的分布,此次统计中的两个 SQL 语句执行时间都在秒级和十秒级。
    • 如下表示如果用户想优化在慢日志中看到的 SQL 语句,可能需要检查表的状态以及表结构,这些就是相关的 SQL 语句。

      SHOW TABLE STATUS FROM `testdb` LIKE 'apple_test'\G
      SHOW CREATE TABLE `testdb`.`apple_test`\G
      
    • delete from apple_test\G 是此类慢 SQL 语句的示例。

    • 如下是 SQL 语句的相关执行计划,但是对于非 select 语句通常不能再次执行来查看执行计划,因此 pt-query-digest 会尝试将 SQL 转化为等效的 select 语句然后展示出来。

      Converted for EXPLAIN
      EXPLAIN /*!50100 PARTITIONS*/
      select * from  apple_test\G
      
这篇文档解决了您的问题吗?
0
0