Skip to content

MySQL Prometheus 与 Grafana 监控

MySQL 监控指标

核心指标

全局状态指标

  • uptime:MySQL 运行时间
  • connections:当前连接数
  • queries:查询总数
  • slow_queries:慢查询数量
  • threads_running:运行中的线程数
  • threads_connected:已连接的线程数

InnoDB 指标

  • buffer_pool_pages_data:缓冲池数据页数
  • buffer_pool_pages_total:缓冲池总页数
  • buffer_pool_read_requests:缓冲池读请求数
  • buffer_pool_write_requests:缓冲池写请求数
  • buffer_pool_hit_ratio:缓冲池命中率
  • innodb_row_lock_waits:行锁等待次数

存储引擎指标

  • innodb_data_read:InnoDB 数据读取量
  • innodb_data_written:InnoDB 数据写入量
  • innodb_os_log_written:InnoDB 日志写入量
  • innodb_buffer_pool_wait_free:缓冲池等待空闲页的次数

查询性能指标

  • query_cache_hits:查询缓存命中次数
  • query_cache_misses:查询缓存未命中次数
  • com_select:SELECT 语句执行次数
  • com_insert:INSERT 语句执行次数
  • com_update:UPDATE 语句执行次数
  • com_delete:DELETE 语句执行次数

系统指标

CPU 指标

  • cpu_seconds_total:CPU 使用率
  • process_cpu_seconds_total:进程 CPU 使用率

内存指标

  • process_resident_memory_bytes:进程内存使用量
  • process_virtual_memory_bytes:进程虚拟内存使用量

磁盘指标

  • disk_read_bytes_total:磁盘读取字节数
  • disk_write_bytes_total:磁盘写入字节数
  • disk_io_time_seconds_total:磁盘 I/O 时间

监控系统部署

Prometheus 部署

安装 Prometheus

二进制安装
bash
# 下载 Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.40.0/prometheus-2.40.0.linux-amd64.tar.gz

# 解压
 tar -xzf prometheus-2.40.0.linux-amd64.tar.gz
cd prometheus-2.40.0.linux-amd64

# 启动 Prometheus
./prometheus --config.file=prometheus.yml
Docker 安装
bash
# 运行 Prometheus 容器
docker run -d -p 9090:9090 \
  -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

配置 Prometheus

基本配置
yaml
# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'mysql'
    static_configs:
      - targets: ['localhost:9104']
    metrics_path: /metrics
    params:
      collect[]: ['global_status', 'global_variables', 'innodb_metrics', 'performance_schema']
服务发现配置
yaml
# 使用文件服务发现
scrape_configs:
  - job_name: 'mysql'
    file_sd_configs:
      - files: ['/path/to/mysql_targets.yml']

MySQL Exporter 部署

安装 MySQL Exporter

二进制安装
bash
# 下载 MySQL 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
Docker 安装
bash
# 运行 MySQL Exporter 容器
docker run -d -p 9104:9104 \
  -v /path/to/.my.cnf:/etc/my.cnf \
  --name mysqld_exporter \
  prom/mysqld-exporter

配置 MySQL Exporter

创建 MySQL 用户
sql
-- 创建监控用户
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'password' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;
配置文件
ini
# .my.cnf
[client]
user=exporter
password=password
host=localhost
port=3306
启动 MySQL Exporter
bash
# 启动 MySQL Exporter
./mysqld_exporter --config.my-cnf=/path/to/.my.cnf

Grafana 部署

安装 Grafana

二进制安装
bash
# 下载 Grafana
wget https://dl.grafana.com/oss/release/grafana-9.0.0.linux-amd64.tar.gz

# 解压
 tar -xzf grafana-9.0.0.linux-amd64.tar.gz
cd grafana-9.0.0

# 启动 Grafana
./bin/grafana-server
Docker 安装
bash
# 运行 Grafana 容器
docker run -d -p 3000:3000 \
  -v /path/to/grafana-storage:/var/lib/grafana \
  grafana/grafana

配置 Grafana

添加 Prometheus 数据源
  1. 登录 Grafana 界面(默认端口 3000)
  2. 点击左侧菜单的 "Configuration" -> "Data sources"
  3. 点击 "Add data source"
  4. 选择 "Prometheus"
  5. 配置 Prometheus 服务器 URL
  6. 点击 "Save & Test"
导入 MySQL 仪表板
  1. 点击左侧菜单的 "Dashboards"
  2. 点击 "Import"
  3. 输入仪表板 ID(如 7362,MySQL Overview)
  4. 选择 Prometheus 数据源
  5. 点击 "Import"

监控仪表板设计

核心仪表板

MySQL 概览仪表板

  • 服务器状态:运行时间、版本、连接数
  • 查询性能:QPS、慢查询、查询类型分布
  • 缓冲池状态:命中率、使用情况
  • 存储引擎:InnoDB 状态、I/O 统计
  • 系统资源:CPU、内存、磁盘使用情况

MySQL 详情仪表板

  • 连接详情:连接数趋势、连接状态
  • 查询详情:各类查询执行次数
  • 缓冲池详情:缓冲池细分指标
  • 锁详情:行锁、表锁等待
  • 复制状态:主从复制延迟、状态

自定义仪表板

业务相关仪表板

  • 业务查询性能:关键业务查询执行时间
  • 业务表状态:核心表大小、索引使用情况
  • 业务指标:交易数、用户数等业务指标

告警专用仪表板

  • 告警状态:当前活动告警
  • 告警历史:告警触发和恢复历史
  • 告警统计:告警类型分布

告警配置

Prometheus 告警规则

基本规则

yaml
# mysql_alerts.yml
groups:
- name: mysql_alerts
  rules:
  - alert: MySQLDown
    expr: mysql_up == 0
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "MySQL 实例宕机"
      description: "MySQL 实例 {{ $labels.instance }} 已宕机超过 5 分钟"

  - alert: MySQLHighConnections
    expr: mysql_global_status_threads_connected > 80
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "MySQL 连接数过高"
      description: "MySQL 实例 {{ $labels.instance }} 连接数超过 80,当前值: {{ $value }}"

  - alert: MySQLSlowQueries
    expr: rate(mysql_global_status_slow_queries[5m]) > 10
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "MySQL 慢查询增多"
      description: "MySQL 实例 {{ $labels.instance }} 慢查询率超过 10/5 分钟,当前值: {{ $value }}"

高级规则

yaml
  - alert: MySQLInnoDBBufferPoolHitRatioLow
    expr: 100 * (1 - (rate(mysql_global_status_innodb_buffer_pool_reads[5m]) / rate(mysql_global_status_innodb_buffer_pool_read_requests[5m]))) < 95
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "MySQL InnoDB 缓冲池命中率低"
      description: "MySQL 实例 {{ $labels.instance }} 缓冲池命中率低于 95%,当前值: {{ $value }}%"

  - alert: MySQLReplicationLag
    expr: mysql_slave_status_sql_delay > 30
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "MySQL 复制延迟"
      description: "MySQL 实例 {{ $labels.instance }} 复制延迟超过 30 秒,当前值: {{ $value }} 秒"

Alertmanager 配置

基本配置

yaml
# alertmanager.yml
global:
  resolve_timeout: 5m

route:
  group_by: ['alertname', 'instance']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'email'

receivers:
- name: 'email'
  email_configs:
  - to: 'alerts@example.com'
    send_resolved: true

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'instance']

高级配置

yaml
# 包含通知渠道配置
receivers:
- name: 'team-X-mails'
  email_configs:
  - to: 'team-X@example.com'

- name: 'team-Y-mails'
  email_configs:
  - to: 'team-Y@example.com'

route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 3h
  receiver: 'team-X-mails'
  routes:
  - match:
      service: mysql
    receiver: 'team-Y-mails'
    group_wait: 10s

监控最佳实践

部署最佳实践

高可用部署

  • Prometheus 高可用:部署多个 Prometheus 实例,使用 Thanos 或 Cortex 实现长期存储
  • Grafana 高可用:部署多个 Grafana 实例,使用共享数据库
  • MySQL Exporter 部署:每个 MySQL 实例部署一个 Exporter

资源配置

  • Prometheus 存储:根据数据量配置适当的存储
  • Grafana 资源:根据仪表板数量和复杂度配置资源
  • 监控频率:根据业务需求调整抓取间隔

监控策略

分层监控

  • 基础设施层:CPU、内存、磁盘监控
  • 数据库层:MySQL 核心指标监控
  • 业务层:关键业务指标监控

告警策略

  • 告警分级:critical、warning、info 三级告警
  • 告警抑制:高级别告警抑制低级别告警
  • 告警路由:根据服务和严重程度路由告警
  • 告警静默:维护期间设置告警静默

性能优化

Prometheus 优化

  • 减少时间序列:只采集必要的指标
  • 调整存储保留:根据需求设置存储保留时间
  • 使用记录规则:预计算复杂查询
  • 水平扩展:使用 Prometheus 联邦集群

Grafana 优化

  • 仪表板优化:减少面板数量,使用变量
  • 查询优化:使用记录规则,避免复杂查询
  • 缓存配置:启用查询结果缓存
  • 资源限制:设置用户和API限制

案例分析

案例1:MySQL 慢查询监控

背景

  • 某电商网站需要监控慢查询,及时发现性能问题
  • 使用 Prometheus 和 Grafana 构建监控系统

实施

  1. 部署 MySQL Exporter:采集慢查询指标
  2. 配置 Prometheus:设置抓取间隔为 10 秒
  3. 创建告警规则:慢查询率超过阈值触发告警
  4. 设计仪表板:慢查询趋势、慢查询类型分布

结果

  • 成功监控到慢查询峰值
  • 及时发现并优化了慢查询
  • 业务高峰期性能稳定

案例2:MySQL 复制监控

背景

  • 某金融系统使用主从复制架构
  • 需要监控复制状态和延迟

实施

  1. 部署 MySQL Exporter:采集复制指标
  2. 配置告警规则:复制延迟超过 30 秒触发告警
  3. 设计复制仪表板:复制状态、延迟趋势
  4. 集成告警通知:通过邮件和短信通知

结果

  • 成功监控到复制延迟
  • 及时发现并解决复制问题
  • 确保数据一致性

案例3:MySQL 资源使用监控

背景

  • 某 SaaS 平台需要监控 MySQL 资源使用情况
  • 确保服务质量和成本控制

实施

  1. 部署监控系统:Prometheus + Grafana + MySQL Exporter
  2. 监控资源指标:CPU、内存、磁盘、网络
  3. 设置资源告警:资源使用率超过阈值触发告警
  4. 设计资源仪表板:资源使用趋势、预测

结果

  • 成功监控资源使用情况
  • 优化资源配置,降低成本
  • 提高服务质量

常见问题与解决方案

监控系统问题

Prometheus 存储问题

  • 症状:存储增长过快,查询变慢
  • 解决方案:调整存储保留时间,使用记录规则,考虑长期存储方案

MySQL Exporter 采集问题

  • 症状:指标采集失败,Exporter 崩溃
  • 解决方案:检查 MySQL 用户权限,调整 Exporter 配置,增加资源限制

Grafana 性能问题

  • 症状:仪表板加载慢,查询超时
  • 解决方案:优化仪表板,使用记录规则,调整缓存配置

监控配置问题

告警误报

  • 症状:告警频繁触发,实际无问题
  • 解决方案:调整告警阈值,增加持续时间,优化告警规则

指标缺失

  • 症状:某些指标未采集或显示
  • 解决方案:检查 Exporter 配置,确认 MySQL 版本支持,调整采集参数

仪表板显示问题

  • 症状:图表显示异常,数据不准确
  • 解决方案:检查查询语句,确认数据源配置,调整图表设置

未来趋势

监控技术发展

智能化监控

  • AI 辅助监控:使用机器学习检测异常
  • 自动根因分析:自动分析性能问题根因
  • 预测性告警:基于趋势预测潜在问题

云原生监控

  • Kubernetes 集成:原生支持容器环境
  • 服务网格监控:与 Istio 等服务网格集成
  • 多云监控:统一监控多云环境

MySQL 监控发展

MySQL 8.0 监控增强

  • Performance Schema 增强:更多细粒度指标
  • JSON 格式指标:更灵活的指标结构
  • 动态监控:实时调整监控策略

开源工具集成

  • Prometheus 原生集成:MySQL 内置 Prometheus 支持
  • OpenTelemetry 集成:与 OpenTelemetry 生态系统集成
  • Grafana 插件:专用 MySQL 监控插件

常见问题(FAQ)

Q1: 如何选择合适的监控指标?

A1: 选择监控指标应考虑:

  • 业务需求:根据业务重要性选择指标
  • 系统特性:根据 MySQL 版本和配置选择指标
  • 资源限制:考虑监控系统的资源限制
  • 告警需求:选择需要告警的关键指标

Q2: 如何优化监控系统性能?

A2: 优化监控系统性能的方法:

  • 减少采集指标数量:只采集必要指标
  • 调整采集间隔:根据指标变化频率调整
  • 使用记录规则:预计算复杂查询
  • 合理配置存储:根据需求设置存储保留

Q3: 如何设置合理的告警阈值?

A3: 设置告警阈值的方法:

  • 基于基线:根据历史数据建立基线
  • 基于业务需求:根据业务容忍度设置
  • 基于经验:参考行业最佳实践
  • 动态调整:根据系统变化调整阈值

Q4: 如何监控多个 MySQL 实例?

A4: 监控多个 MySQL 实例的方法:

  • 每个实例部署一个 MySQL Exporter
  • 使用 Prometheus 服务发现自动发现实例
  • 配置标签区分不同实例
  • 设计统一的仪表板,使用变量切换实例

Q5: 如何实现监控系统的高可用?

A5: 实现监控系统高可用的方法:

  • Prometheus:部署多个实例,使用 Thanos 或 Cortex
  • Grafana:部署多个实例,使用共享数据库
  • MySQL Exporter:每个 MySQL 实例部署一个
  • 告警系统:部署多个 Alertmanager 实例