Prometheus实战教程 - mysql监控

Prometheus 监控 MySQL

一、架构说明

核心逻辑:MySQL 实例注册到 Consul(服务注册)→ Prometheus 配置 Consul 服务发现(自动发现 MySQL 实例)→ MySQL 暴露监控指标(via mysqld_exporter)→ Prometheus 拉取指标 → 可视化/告警。

组件角色

  • Consul:服务注册中心,存储 MySQL 服务的地址、端口、元数据(如用户名、密码)。
  • mysqld_exporter:MySQL 监控指标采集器,部署在 MySQL 节点(或独立部署),连接 MySQL 并暴露 /metrics 接口。
  • Prometheus:通过 Consul 发现所有 MySQL 实例,定期拉取 mysqld_exporter 的指标。
  • MySQL:被监控目标,需开启远程访问权限(供 exporter 连接)。

二、前置条件

  1. 已部署 Consul 集群(单节点可用于测试),确保 Prometheus 能访问 Consul 的 HTTP 接口(默认 8500 端口)。
  2. 已部署 Prometheus(2.x+ 版本),配置文件可编辑。
  3. MySQL 实例(5.7+ 或 8.0+),支持远程连接(防火墙开放 3306 端口)。
  4. 所有组件网络互通:Prometheus ↔ Consul、Prometheus ↔ mysqld_exporter、mysqld_exporter ↔ MySQL。

三、步骤 1:部署 mysqld_exporter(MySQL 指标采集)

mysqld_exporter 是 Prometheus 官方提供的 MySQL 监控采集器,需在每个 MySQL 节点(或独立节点)部署。

3.1 下载并安装 mysqld_exporter

# 下载最新版本(可替换为官网最新版本)
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.18.0/mysqld_exporter-0.18.0.linux-amd64.tar.gz

# 解压并移动到指定目录
tar xvf mysqld_exporter-0.18.0.linux-amd64.tar.gz -C /data/monitor/
cd /data/monitor/
mv mysqld_exporter-0.18.0.linux-amd64 mysqld_exporter

# 验证安装
mysqld_exporter --version  # 输出版本信息则成功

3.2 配置 MySQL 授权(供 exporter 连接)

exporter 需要连接 MySQL 采集指标,需创建专用监控用户并授权:

-- 登录 MySQL(本地或远程)
mysql -u root -p

-- 创建监控用户(允许 exporter 所在节点访问,% 表示所有地址,生产建议限制 IP)
CREATE USER 'prometheus'@'127.0.0.1' IDENTIFIED BY 'YourStrongPassword123!';

-- 授予监控所需权限(最小权限原则)
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'prometheus'@'127.0.0.1';

-- 刷新权限
FLUSH PRIVILEGES;

3.3 配置 mysqld_exporter 连接 MySQL

创建 exporter 的配置文件,存储 MySQL 连接信息:

# 创建配置文件目录
mkdir -p /data/monitor/mysqld_exporter/

# 编写配置文件(指定 MySQL 连接信息)
cat > /data/monitor/mysqld_exporter/.my.cnf << EOF
[client]
user=prometheus
password=YourStrongPassword123!
host=127.0.0.1
port=3306
EOF

# 授权(避免权限问题)
chmod 600 /data/monitor/mysqld_exporter/.my.cnf
chown root:root /data/monitor/mysqld_exporter/.my.cnf

3.4 系统服务方式启动 exporter

# 创建系统服务文件
cat > /etc/systemd/system/mysqld-exporter.service << EOF
[Unit]
Description=Prometheus MySQL Exporter
After=network.target

[Service]
User=root
Group=root
ExecStart=/data/monitor/mysqld_exporter/mysqld_exporter --config.my-cnf=/data/monitor/mysqld_exporter/.my.cnf --web.listen-address=:9104
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# 重载服务配置、启动并设置开机自启
systemctl daemon-reload
systemctl start mysqld-exporter
systemctl enable mysqld-exporter

# 验证启动状态(默认暴露 9104 端口)
systemctl status mysqld-exporter
curl http://[IP]:9104/metrics  # 能看到指标则成功

在这里插入图片描述

四、步骤 2:MySQL 服务注册到 Consul

Consul 支持服务注册(手动注册/自动注册),这里提供两种方式(推荐手动注册用于测试,生产可结合 Consul Agent 自动注册)。

方式 1:手动注册(通过 Consul HTTP API)

适合临时测试或少量实例,无需在 MySQL 节点部署 Consul Agent:

# 向 Consul 注册 MySQL 服务(替换以下参数)
# Consul 地址:192.168.37.40:8500(Consul Server 或 Client 的 HTTP 端口)
# 服务名称:mysqld-exporter(Prometheus 后续通过该名称发现)
# 服务地址:192.168.37.21(MySQL 节点 IP,即 mysqld_exporter 所在 IP)
# 服务端口:9104(mysqld_exporter 暴露的端口)
# 元数据(可选):可存储 MySQL 实例名称、环境等,供 Prometheus 筛选

curl http://192.168.37.40:8500/v1/agent/service/register -X PUT -i -H "Content-Type:application/json" -H "X-Consul-Token: f5cc7d96-ba0f-0501-4252-903e059514bb" -d '{
  "ID": "mysql-192.168.37.21:3306",  
  "Name": "mysqld-exporter",
  "Tags": [
    "mysqld-exporter",
    "dev"
  ],
  "Address": "192.168.37.21",
  "Port": 9104,
  "EnableTagOverride": false,
  "Check": {
    "DeregisterCriticalServiceAfter": "90m",
    "HTTP": "http://192.168.37.21:9104/metrics",
    "Interval": "10s",
    "timeout": "2s"
  }
}'

方式 2:自动注册(通过 Consul Agent)

适合生产环境(多实例、动态扩容),需在每个 MySQL 节点部署 Consul Agent(作为 Client 加入 Consul 集群):

  1. 部署 Consul Agent(参考 Consul 官方文档),确保 Agent 已加入集群。
  2. 创建服务注册配置文件
# 在 MySQL 节点(Consul Agent 所在节点)创建服务配置
mkdir -p /etc/consul.d
cat > /etc/consul.d/mysql-monitor.json << EOF
{
  "service": {
    "id": "mysql-$(hostname -i):9104",  # 自动获取 IP 作为唯一 ID
    "name": "mysql-monitor",  # 服务名称(与手动注册一致)
    "port": 9104,
    "tags": ["env=prod", "instance=mysql-slave"],
    "meta": {
      "mysql_host": "$(hostname -i)",
      "mysql_port": 3306
    },
    "checks": [  # 健康检查(可选,Consul 定期检测 exporter 是否存活)
      {
        "http": "http://$(hostname -i):9104/metrics",
        "interval": "10s",
        "timeout": "3s"
      }
    ]
  }
}
EOF
  1. 重启 Consul Agent 加载配置:
systemctl restart consul

验证服务注册结果

访问 Consul UI(默认 http://Consul-IP:8500/ui),在「Services」中查看 mysql-monitor 服务,状态为「Healthy」则注册成功。
在这里插入图片描述

五、步骤 3:Prometheus 配置 Consul 服务发现

修改 Prometheus 配置文件,添加 Consul 服务发现规则,让 Prometheus 自动发现所有注册到 Consul 的 mysql-monitor 服务。

5.1 编辑 Prometheus 配置文件(prometheus.yml)

global:
  scrape_interval: 15s  # 全局拉取间隔

scrape_configs:
  # 其他已有配置(如 node_exporter)...

  # 添加 MySQL 监控的 Consul 服务发现配置
  - job_name: 'mysqld-exporter'  # 任务名称(自定义)
    consul_sd_configs:
      - server: '192.168.37.40:8500'  # Consul 的 HTTP 地址(Server 或 Client)
        datacenter: 'dc1'  # 与 Consul 注册时的 datacenter 一致
        tag_separator: ','
        scheme: 'http'
        services: ['mysqld-exporter']  # 只发现 Consul 中名称为 mysql-monitor 的服务
        # 可选:过滤标签(只发现 tags 包含 env=prod 的服务)
        # filter: 'ServiceTags contains "env=prod"'

    # 可选:重写拉取路径(默认 /metrics,exporter 无需修改则无需配置)
    metrics_path: '/metrics'

    # 可选:添加标签(用于区分环境、实例)
    relabel_configs:
      # 从 Consul 服务的 meta 中提取 mysql_host 作为标签
      - source_labels: [__meta_consul_service_meta_mysql_host]
        target_label: mysql_host
      # 从 Consul 服务的 tags 中提取 env 作为标签
      - source_labels: [__meta_consul_service_tag_env]
        target_label: env
      # 从 Consul 服务的 ID 中提取实例信息
      - source_labels: [__meta_consul_service_id]
        target_label: instance

5.2 验证 Prometheus 配置并重启

# 验证配置文件语法是否正确
promtool check config /etc/prometheus/prometheus.yml

# 重启 Prometheus 加载配置
systemctl restart prometheus

5.3 确认服务发现结果

访问 Prometheus UI(默认 http://Prometheus-IP:9090):

  1. 进入「Status → Targets」,查看 mysql-monitor 任务。
  2. 若所有 MySQL 实例的 State 为「UP」,说明服务发现成功,Prometheus 已开始拉取指标。

在这里插入图片描述

六、步骤 4:可视化监控(Grafana)

Prometheus 本身不擅长可视化,推荐使用 Grafana 导入 MySQL 监控面板。

4.1 导入 MySQL 监控面板

  1. 登录 Grafana(已集成 Prometheus 数据源)。
  2. 进入「Dashboards → Import」,输入 MySQL 官方面板 ID:7362(或搜索「MySQL by Prometheus & mysqld_exporter」)。
  3. 选择 Prometheus 数据源,点击「Import」,即可看到完整的 MySQL 监控面板(包含连接数、QPS、慢查询、表空间、索引命中率等指标)。

七、Mysql监控指标

MySQL 核心监控指标清单(按维度分类)

一、可用性指标(基础必监控)
指标名指标含义核心 PromQL 查询监控意义
mysql_upMySQL 实例是否在线mysql_up直接判断实例是否存活(1=在线,0=离线)
mysql_global_status_uptime实例运行时长(秒)mysql_global_status_uptime检测实例是否频繁重启(数值骤降)
二、连接数指标(避免连接耗尽)
指标名指标含义核心 PromQL 查询监控意义
mysql_global_status_connections当前已建立的连接数mysql_global_status_connections实时查看连接数变化
mysql_global_variables_max_connections最大允许连接数mysql_global_variables_max_connections配置基准值
-连接数使用率mysql_global_status_connections / mysql_global_variables_max_connections核心:超过80%需告警
mysql_global_status_aborted_connects失败的连接尝试数increase(mysql_global_status_aborted_connects[5m])检测密码错误、权限问题等连接失败
三、性能指标(定位慢查询/锁/临时表问题)
指标名指标含义核心 PromQL 查询监控意义
mysql_global_status_slow_queries慢查询总数increase(mysql_global_status_slow_queries[5m])慢查询突增→SQL 性能问题
mysql_global_status_table_locks_waited表锁等待次数increase(mysql_global_status_table_locks_waited[5m])锁等待频繁→长事务/慢 SQL
mysql_global_status_created_tmp_tables临时表创建总数increase(mysql_global_status_created_tmp_tables[5m])临时表过多→SQL 未优化
mysql_global_status_created_tmp_disk_tables磁盘临时表创建数increase(mysql_global_status_created_tmp_disk_tables[5m]) / increase(mysql_global_status_created_tmp_tables[5m])占比超20%→需调优 tmp_table_size
mysql_global_status_handler_read_rnd随机读次数rate(mysql_global_status_handler_read_rnd[1m])数值过高→缺少索引
四、流量指标(QPS/TPS/网络吞吐)
指标名指标含义核心 PromQL 查询监控意义
mysql_global_status_queries总查询数rate(mysql_global_status_queries[1m])计算 QPS(每秒查询数)→流量波动
mysql_global_status_handler_commit事务提交数rate(mysql_global_status_handler_commit[1m]) - rate(mysql_global_status_handler_rollback[1m])计算 TPS(每秒事务数)→写入负载
mysql_global_status_bytes_received网络流入字节总数rate(mysql_global_status_bytes_received[1m])流入流量→数据写入/攻击检测
mysql_global_status_bytes_sent网络流出字节总数rate(mysql_global_status_bytes_sent[1m])流出流量→数据查询/泄露检测
五、存储指标(磁盘/空间)
指标名指标含义核心 PromQL 查询监控意义
mysql_disk_used_bytes数据目录已用磁盘空间mysql_disk_used_bytes实时查看磁盘使用量
mysql_disk_total_bytes数据目录总磁盘空间mysql_disk_used_bytes / mysql_disk_total_bytes使用率超85%→需扩容/清理
mysql_global_status_disk_full磁盘满错误数increase(mysql_global_status_disk_full[5m])检测磁盘满导致的写失败
六、主从复制指标(同步状态)
指标名指标含义核心 PromQL 查询监控意义
mysql_slave_seconds_behind_master从库延迟秒数mysql_slave_seconds_behind_master延迟超60秒→同步异常
mysql_slave_io_runningIO 线程是否运行mysql_slave_io_running (1=运行,0=停止)IO 线程停止→同步中断
mysql_slave_sql_runningSQL 线程是否运行mysql_slave_sql_running (1=运行,0=停止)SQL 线程停止→数据同步失败

八、告警

告警规则

groups:
- name: mysql_alerts
  rules:
  # ========== 基础可用性告警 ==========
  # 1. MySQL 服务不可用
  - alert: MySQLDown
    expr: mysql_up == 0
    for: 30s
    labels:
      severity: critical
      service: mysql
    annotations:
      summary: "MySQL 服务不可用 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 已下线超过 30 秒,请检查服务状态。"

  # 2. MySQL 连接数过高
  - alert: MySQLTooManyConnections
    expr: mysql_global_status_connections / mysql_global_variables_max_connections > 0.8
    for: 2m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 连接数过高 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 连接数使用率超过 80% (当前: {{ $value | humanizePercentage }}),请检查是否有连接泄露或业务突增。"

  # 3. MySQL 慢查询数突增
  - alert: MySQLSlowQueriesIncreasing
    expr: increase(mysql_global_status_slow_queries[5m]) > 10
    for: 5m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 慢查询数突增 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 最近 5 分钟慢查询数增加了 {{ $value }} 个,需检查慢查询日志优化 SQL。"

  # 4. MySQL 磁盘使用率过高(数据目录)
  - alert: MySQLDiskUsageHigh
    expr: mysql_disk_used_bytes / mysql_disk_total_bytes > 0.85
    for: 5m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 磁盘使用率过高 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 数据目录磁盘使用率超过 85% (当前: {{ $value | humanizePercentage }}),请清理数据或扩容磁盘。"

  # 5. MySQL 主从复制延迟
  - alert: MySQLReplicationLag
    expr: mysql_slave_seconds_behind_master > 60
    for: 2m
    labels:
      severity: critical
      service: mysql
    annotations:
      summary: "MySQL 主从复制延迟 ({{ $labels.instance }})"
      description: "MySQL 从库 {{ $labels.instance }} 复制延迟超过 60 秒 (当前: {{ $value }} 秒),请检查主从同步状态。"

  # 6. MySQL 表锁等待时间过长
  - alert: MySQLTableLockWaits
    expr: mysql_global_status_table_locks_waited > 0 and increase(mysql_global_status_table_locks_waited[5m]) > 10
    for: 1m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 表锁等待频繁 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 最近 5 分钟表锁等待数增加 {{ $value }} 次,可能存在长事务或慢 SQL。"

  # 7. MySQL 临时表创建过多(磁盘临时表)
  - alert: MySQLTempTablesOnDisk
    expr: increase(mysql_global_status_created_tmp_disk_tables[5m]) / increase(mysql_global_status_created_tmp_tables[5m]) > 0.2
    for: 5m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 磁盘临时表占比过高 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 磁盘临时表占比超过 20% (当前: {{ $value | humanizePercentage }}),需优化 SQL 或调整 tmp_table_size 配置。"

  # ========== 流量相关告警(修正核心指标名) ==========
  # 8. MySQL 每秒查询量(QPS)突增
  - alert: MySQLQPSHigh
    expr: rate(mysql_global_status_queries[1m]) > 5000  # 标准指标名:mysql_global_status_queries
    for: 2m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL QPS 突增 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 每秒查询量超过 5000 (当前: {{ $value | humanize }}),可能存在流量洪峰或异常查询。"

  # 9. MySQL 每秒查询量(QPS)突降
  - alert: MySQLQPSLow
    expr: rate(mysql_global_status_queries[1m]) < 100  # 标准指标名:mysql_global_status_queries
    for: 5m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL QPS 突降 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 每秒查询量低于 100 (当前: {{ $value | humanize }}),可能存在业务中断或采集异常。"

  # 10. MySQL 网络流入流量过高
  - alert: MySQLNetworkInHigh
    expr: rate(mysql_global_status_bytes_received[1m]) > 10485760  # 10MB/s,标准指标名
    for: 3m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 流入流量过高 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 每秒流入流量超过 10MB (当前: {{ $value | humanizeBytes }}/s),可能存在大量数据写入或网络攻击。"

  # 11. MySQL 网络流出流量过高
  - alert: MySQLNetworkOutHigh
    expr: rate(mysql_global_status_bytes_sent[1m]) > 10485760  # 10MB/s,标准指标名
    for: 3m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL 流出流量过高 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 每秒流出流量超过 10MB (当前: {{ $value | humanizeBytes }}/s),可能存在大量数据查询或数据泄露风险。"

  # 12. MySQL 每秒写入量(TPS)突增
  - alert: MySQLTPSHigh
    expr: rate(mysql_global_status_handler_commit[1m]) - rate(mysql_global_status_handler_rollback[1m]) > 1000  # 标准指标名
    for: 2m
    labels:
      severity: warning
      service: mysql
    annotations:
      summary: "MySQL TPS 突增 ({{ $labels.instance }})"
      description: "MySQL 实例 {{ $labels.instance }} 每秒事务数超过 1000 (当前: {{ $value | humanize }}),可能存在批量写入或业务峰值。"

压测和告警

关于Mysql压测,之前写过一个文章
MySQL 压测实战:sysbench 从入门到精通

关于告警配置(钉钉)
告警通知实现 - 邮件 + 钉钉 + 自定义告警模板

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值