实时监控MySQL慢查询

背景

为了优化SQL,我们首先需要发现有问题的SQL语句,网上诸多教程都在教你使用诸如mysqldumpslowpt-query-digest这类工具分析MySQL慢查询日志。然而这一系列的工具都存在一个致命的缺陷,无法实时监控。

而说起实时监控,有经验的小伙伴可能都会想到 mysqld_exporter + prometheus + grafana 的组合,再结合Grafana官网提供的MySQL 模板,便可以实时监控Mysql的多项指标,如下图所示:

请添加图片描述

然而,该方案仅能让我们知道什么时候发生了慢查询,却无法直接看出发生慢查询的SQL语句是什么。于是乎便有了该篇博文的诞生。

本小节我们将使用 promtail + loki + grafana 来实现MySQL慢查询的可视化。直接将慢查询的SQL语句显示在grafana中,如下图所示:

请添加图片描述

实现步骤

1. 启用MySQL的慢查询日志

在MySQL中开启慢查询日志的方法有很多种,这里我们以在my.cnf配置文件中开启为例,找到my.cnf文件,添加以下配置:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2

其中,slow_query_log表示开启慢查询日志功能,slow_query_log_file表示慢查询日志文件的路径,long_query_time表示查询执行时间超过多少秒才被记录到慢查询日志中。

2. 采集MySQL的慢查询日志

市面上的日志采集工具同样很多,如Logstash、Fluentd等,你可以使用你喜欢的日志采集工具,本文中使用grafana官方提供的 promtail,其部署脚本如下:

docker-compose.yaml

version: "3"
services:
  promtail:
    image: grafana/promtail:2.7.0
    volumes:
      - /var/log/mysql:/var/log/mysql
      - /etc/promtail/promtail-config.yaml:/etc/promtail/promtail-config.yaml
    command: -config.file=/etc/promtail/promtail-config.yaml

promtail-config.yamlpromtail的配置文件,具体内容如下:

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: mysql-slow
    static_configs:
      - targets:
          - localhost
        labels:
          job: mysql-slow
          __path__: /var/log/mysql/*.log
    pipeline_stages:
      - match:
          selector: '{job="mysql-slow"}'
          stages:
            - multiline:
                firstline: '^(# Time)'
                max_wait_time: 3s

其中,__path__用于指定采集日志的位置;multiline 表示合并多行Mysql慢查询日志为一行,firstline指定了多行日志的起始行

通过运行promtail,日志将被采集并推送到 loki 中进行存储。接下去我们只要将其读取并进行展示即可。

3. 配置Grafana

在Grafana → Explore中,通过查询语句{filename="/var/log/mysql/mysql-slow.log",job="mysql-slow"},便可查询到MySQL慢查询日志,如下图所示:

请添加图片描述

同时,你也可以在DashBoards中直接配置可视化面板,例如:

请添加图片描述

例子中使用到的Loki查询语句如下:

sum(count_over_time({filename="/var/log/mysql/mysql-slow.log",job="mysql-slow"} | pattern "# Time: <time>\n# User@Host: <user>[<root>] @  [<ip>]  Id:   <id>\n# Query_time: <queryTime>  Lock_time: <lockTime> Rows_sent: <rowsSent>  Rows_examined: <rowsExamined>\nSET timestamp=<timestamp>;\n<sql>;"[1m])) by (sql)

其中,pattern 从日志行中提取字段,字段和MySQL慢查询日志的对应关系如下:

# Time: 2023-05-24T08:03:10.794543Z
# User@Host: root[root] @  [192.168.61.1]  Id:   191
# Query_time: 5.001091  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 1
SET timestamp=1684915385;
SELECT SLEEP(5);
# Time: <time>
# User@Host: <user>[<root>] @  [<ip>]  Id:   <id>
# Query_time: <queryTime>  Lock_time: <lockTime> Rows_sent: <rowsSent>  Rows_examined: <rowsExamined>
SET timestamp=<timestamp>;
<sql>;

对于出现换行的地方,需要使用\n代替,便得到了我们最终的表达式

# Time: <time>\n# User@Host: <user>[<host>] @  [<ip>]  Id:   <id>\n# Query_time: <queryTime>  Lock_time: <lockTime> Rows_sent: <rowsSent>  Rows_examined: <rowsExamined>\nSET timestamp=<timestamp>;\n<sql>;

按照同样的方式,你可以做出更多的DashBoards面板,这里就不在演示,小伙伴们可根据自己的需求进行定制。

4. 测试

你可以使用线上真实的慢查询SQL语句进行测试,也可以为了方便简单,和小编一样,使用 SLEEP() 阻塞执行的方式进行测试,如下:

SELECT SLEEP(5);

阻塞5秒执行。

小结

到此,我们使用 promtail + loki + grafana 的组合完成了MySQL慢查询的可视化,将慢查询的SQL语句直接显示在grafana中。但我们不应该局限于 promtail + loki + grafana 的组合,而应该扩展思路,既然promtail + loki + grafana 组合可以,那 ElasticSearch + Logstash + Kibana 等其他组合同样可以。只要敢想敢干,路总会有的!加油

参考文档

LogQL: Log query language | Grafana Loki documentation

MySQL Overview | Grafana Labs

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于MySQL慢查询优化,有几个常见的方法和技巧可以尝试: 1. 确定慢查询:首先使用MySQL慢查询日志或性能分析工具(如Percona Toolkit)来确定哪些查询较慢。这样可以帮助你了解具体的问题。 2. 优化查询语句:检查慢查询中的SQL语句并进行优化。你可以考虑添加适当的索引以提高查询性能,或者重写复杂的查询语句以简化其逻辑。 3. 优化数据库结构:检查数据库表的设计和结构,确保表中的字段类型、索引和约束等设置是合理的。合理的数据库设计可以提高查询性能。 4. 避免全表扫描:尽量避免在大表上执行全表扫描操作,可以通过添加索引或者改进查询条件来避免全表扫描。 5. 调整系统配置参数:根据数据库负载和硬件性能,调整MySQL的配置参数,如缓冲区大小、连接池大小等,以提高系统性能。 6. 使用缓存:考虑使用缓存技术(如Redis)来缓存常用的查询结果,减轻数据库的压力。 7. 分离读写操作:将读操作和写操作分离到不同的数据库实例或服务器上,可以提高数据库的并发性能。 8. 使用慢查询日志或监控工具:定期分析慢查询日志,或者使用监控工具(如Prometheus和Grafana)来实时监测数据库性能,并及时调整和优化。 这些是一些常见的MySQL慢查询优化方法,具体的优化策略需要根据具体情况进行调整和实施。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值