MySQL高级讲座篇之:如何将MySQL的`Performance Schema`数据,实时同步到`Prometheus`进行可视化监控?

各位观众老爷,大家好!今天给大家带来一场干货满满的MySQL监控盛宴,主题是:如何把MySQL的Performance Schema数据,实时同步到Prometheus进行可视化监控。准备好你的瓜子饮料小板凳,咱们这就开始!

开场白:监控,监控,一切为了稳定!

话说江湖行走,最怕的就是系统突然崩了。这时候,监控就像你的千里眼、顺风耳,能让你提前发现问题,避免悲剧发生。MySQL作为数据库界的扛把子,监控更是重中之重。

传统的MySQL监控方式,要么是手动执行SQL查看状态,要么是用一些商业监控工具。前者效率低,后者成本高。有没有一种既高效又经济的方案呢?答案是肯定的!那就是:Performance Schema + mysqld_exporter + Prometheus + Grafana 的黄金组合!

第一部分:Performance Schema,MySQL的秘密武器

Performance Schema是MySQL 5.5版本之后引入的一个性能监控神器。它收集了MySQL服务器运行时的各种信息,包括查询执行时间、锁等待、I/O操作等等。有了它,你就相当于拥有了MySQL内部的X光机,可以清晰地看到MySQL的运行状态。

1.1 开启Performance Schema

默认情况下,Performance Schema可能是关闭的。我们需要手动开启它。

-- 查看 Performance Schema 是否开启
SELECT @@performance_schema;

-- 开启 Performance Schema
UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES';
UPDATE performance_schema.setup_consumers SET enabled = 'YES';
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;

-- 或者修改 MySQL 配置文件 (my.cnf 或 my.ini)
[mysqld]
performance_schema=ON

-- 重启 MySQL 服务

温馨提示: 开启Performance Schema会带来一定的性能开销,但通常可以忽略不计。如果你的MySQL服务器资源非常紧张,可以考虑只开启部分监控项。

1.2 Performance Schema的表结构

Performance Schema包含大量的表,每个表都记录了不同方面的性能数据。下面列出一些常用的表:

表名 描述
events_statements_summary_global_by_event_name 按照事件名称统计的全局语句信息,例如 select, insert, update 等的执行次数、总耗时等。
events_waits_summary_global_by_event_name 按照事件名称统计的全局等待事件信息,例如 lock, io, mutex 等的等待次数、总耗时等。
global_status 记录 MySQL 服务器的全局状态变量,例如连接数、线程数、QPS、TPS 等。
global_variables 记录 MySQL 服务器的全局变量。
threads 记录当前正在运行的线程信息。
replication_connection_status 记录复制连接状态信息。
replication_applier_status_by_worker 记录复制应用线程状态信息。

1.3 如何查询Performance Schema

查询Performance Schema的表就像查询普通的MySQL表一样。例如,我们可以查询events_statements_summary_global_by_event_name表,查看各种SQL语句的执行情况:

SELECT
    EVENT_NAME,
    COUNT_STAR,
    SUM_TIMER_WAIT / 1000000000000 AS total_latency_seconds, -- 将纳秒转换为秒
    AVG_TIMER_WAIT / 1000000000000 AS avg_latency_seconds
FROM
    events_statements_summary_global_by_event_name
WHERE
    EVENT_NAME LIKE 'statement/%'
ORDER BY
    SUM_TIMER_WAIT DESC
LIMIT 10;

这条SQL语句会返回执行时间最长的10种SQL语句的执行次数和总耗时。

第二部分:mysqld_exporter,MySQL的搬运工

mysqld_exporter是Prometheus官方提供的MySQL监控exporter。它的作用就像一个搬运工,把Performance Schema中的数据提取出来,转换成Prometheus可以识别的格式,然后通过HTTP接口暴露给Prometheus。

2.1 下载和安装mysqld_exporter

你可以从Prometheus官网下载mysqld_exporter的二进制文件。下载完成后,解压并运行它。

# 下载 mysqld_exporter
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz

# 解压
tar -xzf mysqld_exporter-0.14.0.linux-amd64.tar.gz

# 进入目录
cd mysqld_exporter-0.14.0.linux-amd64

# 运行 mysqld_exporter
./mysqld_exporter --config.my-cnf=/path/to/your/my.cnf

重要提示: --config.my-cnf参数指定了MySQL的配置文件路径。mysqld_exporter会从这个文件中读取MySQL的连接信息。你需要确保这个文件包含正确的MySQL用户名和密码。

2.2 配置MySQL用户权限

mysqld_exporter需要一个具有足够权限的MySQL用户才能读取Performance Schema的数据。建议创建一个专门用于监控的用户,并授予它以下权限:

CREATE USER 'exporter'@'%' IDENTIFIED BY 'your_password';
GRANT PROCESS, REPLICATION CLIENT, SELECT ON performance_schema.* TO 'exporter'@'%';
FLUSH PRIVILEGES;

解释:

  • PROCESS:允许查看MySQL进程信息。
  • REPLICATION CLIENT:允许查看复制状态信息。
  • SELECT ON performance_schema.*:允许读取Performance Schema的所有表。

2.3 验证mysqld_exporter是否正常工作

运行mysqld_exporter后,你可以通过访问http://localhost:9104/metrics来查看它暴露的监控数据。如果一切正常,你应该能看到一大堆以mysql_开头的指标。

第三部分:Prometheus,监控数据的存储和分析中心

Prometheus是一个开源的监控和告警系统。它可以从各种exporter收集监控数据,然后存储在自己的时间序列数据库中。Prometheus还提供了强大的查询语言(PromQL),可以用来分析监控数据,并设置告警规则。

3.1 安装和配置Prometheus

你可以从Prometheus官网下载Prometheus的二进制文件。下载完成后,解压并运行它。

# 下载 Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz

# 解压
tar -xzf prometheus-2.47.0.linux-amd64.tar.gz

# 进入目录
cd prometheus-2.47.0.linux-amd64

# 修改 Prometheus 配置文件 (prometheus.yml)
# 添加 mysqld_exporter 的配置
# scrape_configs:
#   - job_name: 'mysql'
#     static_configs:
#       - targets: ['localhost:9104']

# 运行 Prometheus
./prometheus --config.file=prometheus.yml

重要提示: 你需要在Prometheus的配置文件(prometheus.yml)中添加mysqld_exporter的配置,告诉Prometheus从哪里收集监控数据。

3.2 验证Prometheus是否正常工作

运行Prometheus后,你可以通过访问http://localhost:9090来查看它的Web界面。在Web界面的查询框中输入mysql_up,然后点击"Execute"按钮。如果Prometheus成功收集到mysqld_exporter的数据,你应该能看到mysql_up{instance="localhost:9104",job="mysql"} 1

3.3 使用PromQL查询MySQL监控数据

PromQLPrometheus的查询语言,它非常强大,可以用来查询各种监控数据。下面列出一些常用的PromQL查询语句:

PromQL 查询语句 描述
mysql_global_status_threads_connected 查询当前MySQL的连接数。
rate(mysql_global_status_questions[5m]) 查询过去5分钟内MySQL的QPS(每秒查询数)。
rate(mysql_global_status_commands_total{command="insert"}[5m]) 查询过去5分钟内MySQL的INSERT语句的TPS(每秒事务数)。
sum(rate(mysql_innodb_rows_read[5m])) by (instance) 查询过去5分钟内每个MySQL实例的Innodb读取行数。
sum(rate(mysql_global_status_slow_queries[5m])) by (instance) 查询过去5分钟内每个MySQL实例的慢查询数。
mysql_global_status_uptime 查询MySQL的运行时间(秒)。
mysql_global_status_bytes_received / mysql_global_status_uptime 计算MySQL每秒接收的字节数。
mysql_global_status_bytes_sent / mysql_global_status_uptime 计算MySQL每秒发送的字节数。
(mysql_innodb_buffer_pool_pages_total - mysql_innodb_buffer_pool_pages_free) / mysql_innodb_buffer_pool_pages_total * 100 计算InnoDB缓冲池的使用率(百分比)。
sum(increase(mysql_slave_sql_thread_seconds_behind_master[5m])) by (instance) 查询过去5分钟内每个MySQL从库的延迟(秒)。需要注意的是,这个指标只有在MySQL作为从库时才有效。

你可以把这些PromQL查询语句复制到Prometheus的Web界面中,然后点击"Execute"按钮,查看查询结果。

第四部分:Grafana,监控数据的可视化展示

Grafana是一个开源的数据可视化工具。它可以连接到各种数据源(包括Prometheus),然后把监控数据以各种图表的形式展示出来。有了Grafana,你就可以轻松地创建漂亮的MySQL监控仪表盘。

4.1 安装和配置Grafana

你可以从Grafana官网下载Grafana的安装包。安装完成后,启动Grafana服务。

# 下载 Grafana
wget https://dl.grafana.com/oss/release/grafana_10.2.2_amd64.deb

# 安装 Grafana
sudo dpkg -i grafana_10.2.2_amd64.deb

# 启动 Grafana
sudo systemctl start grafana-server

4.2 添加Prometheus数据源

启动Grafana后,你可以通过访问http://localhost:3000来查看它的Web界面。默认的用户名和密码是admin/admin

登录Grafana后,你需要添加Prometheus数据源,告诉Grafana从哪里读取监控数据。

  1. 点击左侧菜单栏的"Configuration"图标(齿轮)。
  2. 点击"Data sources"。
  3. 点击"Add data source"。
  4. 选择"Prometheus"。
  5. 在"URL"字段中输入Prometheus的地址(例如http://localhost:9090)。
  6. 点击"Save & test"按钮。

4.3 创建MySQL监控仪表盘

添加Prometheus数据源后,你就可以创建MySQL监控仪表盘了。

  1. 点击左侧菜单栏的"Dashboards"图标。
  2. 点击"New dashboard"。
  3. 点击"Add new panel"。
  4. 在"Query"字段中输入PromQL查询语句。
  5. 选择合适的图表类型(例如"Graph", "Gauge", "Stat")。
  6. 调整图表的各种参数(例如标题、颜色、坐标轴)。
  7. 点击"Apply"按钮。

你可以重复以上步骤,添加多个图表,创建一个完整的MySQL监控仪表盘。

4.4 导入现成的Grafana仪表盘

如果你不想自己创建Grafana仪表盘,也可以从Grafana官网导入现成的仪表盘。有很多优秀的MySQL监控仪表盘可供选择。

  1. Grafana官网搜索"MySQL dashboard"。
  2. 找到你喜欢的仪表盘,复制它的ID。
  3. Grafana中,点击左侧菜单栏的"Dashboards"图标。
  4. 点击"Import"。
  5. 在"Import via grafana.com"字段中输入仪表盘的ID。
  6. 点击"Load"按钮。
  7. 选择Prometheus数据源。
  8. 点击"Import"按钮。

第五部分:实战案例:监控MySQL的慢查询

慢查询是MySQL性能问题的重要原因之一。我们可以使用Performance Schema + mysqld_exporter + Prometheus + Grafana 来监控MySQL的慢查询。

5.1 开启MySQL的慢查询日志

首先,我们需要开启MySQL的慢查询日志,并设置慢查询的时间阈值。

-- 查看慢查询日志是否开启
SHOW VARIABLES LIKE 'slow_query_log';

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';

-- 设置慢查询的时间阈值 (单位:秒)
SET GLOBAL long_query_time = 1;

-- 指定慢查询日志文件路径 (可选)
-- SET GLOBAL slow_query_log_file = '/path/to/your/slow_query.log';

5.2 使用Performance Schema查询慢查询

Performance Schemaevents_statements_summary_global_by_event_name表记录了所有SQL语句的执行情况,包括慢查询。我们可以通过查询这个表来获取慢查询的信息。

SELECT
    EVENT_NAME,
    COUNT_STAR,
    SUM_TIMER_WAIT / 1000000000000 AS total_latency_seconds,
    AVG_TIMER_WAIT / 1000000000000 AS avg_latency_seconds
FROM
    events_statements_summary_global_by_event_name
WHERE
    EVENT_NAME LIKE 'statement/%'
    AND SUM_TIMER_WAIT > 1000000000 -- 过滤掉执行时间小于1秒的语句
ORDER BY
    SUM_TIMER_WAIT DESC
LIMIT 10;

5.3 在Grafana中创建慢查询监控图表

我们可以使用以下PromQL查询语句,在Grafana中创建一个慢查询监控图表:

sum(rate(mysql_global_status_slow_queries[5m])) by (instance)

这条PromQL查询语句会返回过去5分钟内每个MySQL实例的慢查询数。

第六部分:总结与展望

今天我们学习了如何使用Performance Schema + mysqld_exporter + Prometheus + Grafana 来监控MySQL。这种方案具有以下优点:

  • 高效: Performance Schema 提供了丰富的性能数据,可以帮助我们快速定位问题。
  • 经济: 所有组件都是开源的,可以大大降低监控成本。
  • 灵活: PrometheusGrafana 提供了强大的查询和可视化能力,可以满足各种监控需求。

当然,这种方案也存在一些缺点:

  • 配置复杂: 需要配置多个组件,有一定的学习成本。
  • 性能开销: 开启Performance Schema会带来一定的性能开销。

未来,我们可以进一步优化这种方案,例如:

  • 使用Alertmanager 设置告警规则,及时发现问题。
  • 使用Kubernetes 部署 PrometheusGrafana,提高可用性。
  • 定制 mysqld_exporter,只采集需要的指标,降低性能开销。

好了,今天的讲座就到这里。希望大家能够学以致用,打造一个强大的MySQL监控系统,让你的MySQL服务器永不宕机! 谢谢大家!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注