1. 为什么需要监控MySQL数据库?
MySQL作为最流行的开源关系型数据库之一,承载着大量关键业务数据。我在实际运维工作中发现,数据库性能问题往往是系统瓶颈的根源。一次慢查询可能导致整个应用响应延迟,连接数耗尽会造成服务不可用,而这些问题通常不会立即触发数据库崩溃,而是像慢性病一样逐渐影响系统健康。
传统监控方式存在三个明显缺陷:一是被动式监控,往往等问题出现后才去排查;二是指标分散,不同维度的数据难以关联分析;三是缺乏历史趋势,无法进行容量规划。这正是Prometheus监控方案的价值所在——它提供了多维数据模型、强大的查询语言和高效的时间序列存储,特别适合数据库这类需要长期观察的系统组件。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 监控方案整体架构设计
2.1 核心组件选型
完整的监控体系包含三个关键组件:
- 数据采集层:mysqld_exporter作为Prometheus的官方导出器,专门用于收集MySQL指标
- 存储计算层:Prometheus server负责抓取、存储和处理时间序列数据
- 可视化层:Grafana提供灵活的仪表板展示能力
这种架构的优势在于各组件职责明确,且全部是开源软件。我在多个生产环境验证过其稳定性,单台服务器就能支撑日均千万级指标的采集。
2.2 指标采集原理
mysqld_exporter通过定期执行SHOW STATUS、SHOW VARIABLES等SQL语句获取数据库状态,将其转换为Prometheus格式的metrics。关键指标包括:
- 连接数(Threads_connected)
- 查询吞吐量(Questions)
- InnoDB缓冲池命中率(innodb_buffer_pool_read_requests)
- 慢查询数量(Slow_queries)
这些指标通过HTTP接口暴露,Prometheus会按配置的间隔(通常15-30秒)主动拉取数据。这种pull模式相比传统push方案更利于集中管理。
3. 详细部署实施步骤
3.1 环境准备
建议使用Linux系统部署,以下示例基于CentOS 7:
bash复制# 创建专用用户
useradd -M -s /bin/false prometheus
useradd -M -s /bin/false mysqld_exporter
# 安装基础依赖
yum install -y wget tar gzip
3.2 MySQL监控账号配置
在MySQL中创建专用监控账号(需SUPER权限):
sql复制CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'StrongPassword' WITH MAX_USER_CONNECTIONS 3;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;
重要安全提示:务必限制该账号的连接数,避免监控系统影响数据库性能
3.3 mysqld_exporter安装
bash复制VERSION="0.14.0"
wget https://github.com/prometheus/mysqld_exporter/releases/download/v${VERSION}/mysqld_exporter-${VERSION}.linux-amd64.tar.gz
tar xvfz mysqld_exporter-*.tar.gz
mv mysqld_exporter-*.linux-amd64 /usr/local/bin/mysqld_exporter
创建配置文件/etc/.my.cnf:
ini复制[client]
user=exporter
password=StrongPassword
3.4 启动配置
创建systemd服务文件/etc/systemd/system/mysqld_exporter.service:
ini复制[Unit]
Description=MySQL Prometheus Exporter
After=network.target
[Service]
User=mysqld_exporter
Group=mysqld_exporter
ExecStart=/usr/local/bin/mysqld_exporter \
--config.my-cnf=/etc/.my.cnf \
--collect.global_status \
--collect.info_schema.innodb_metrics \
--collect.auto_increment.columns \
--collect.info_schema.processlist \
--collect.binlog_size \
--collect.info_schema.tablestats \
--collect.global_variables \
--collect.info_schema.query_response_time \
--collect.info_schema.userstats \
--collect.info_schema.tables \
--collect.perf_schema.tablelocks \
--collect.perf_schema.file_events \
--collect.perf_schema.eventswaits \
--collect.perf_schema.indexiowaits \
--collect.perf_schema.tableiowaits \
--collect.slave_status \
--web.listen-address=0.0.0.0:9104
Restart=always
[Install]
WantedBy=multi-user.target
启动服务:
bash复制systemctl daemon-reload
systemctl enable mysqld_exporter
systemctl start mysqld_exporter
3.5 Prometheus服务配置
在prometheus.yml中添加job配置:
yaml复制scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['mysql-server:9104']
metrics_path: /metrics
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: 'production-mysql-01'
4. 关键监控指标解析
4.1 性能类指标
| 指标名称 | 正常范围 | 告警阈值 | 说明 |
|---|---|---|---|
| mysql_global_status_questions | 依业务而定 | 同比突降50% | 查询吞吐量 |
| mysql_global_status_slow_queries | < 1%总查询量 | > 5%总查询量 | 慢查询数量 |
| mysql_global_status_innodb_row_lock_time_avg | < 500ms | > 1s | 行锁平均等待时间 |
4.2 资源类指标
promql复制# 连接数使用率
mysql_global_status_threads_connected / mysql_global_variables_max_connections * 100
# 缓冲池命中率
1 - (
mysql_global_status_innodb_buffer_pool_reads
/ mysql_global_status_innodb_buffer_pool_read_requests
) * 100
4.3 复制状态监控
对于主从架构,这些指标尤为重要:
- mysql_global_status_slave_io_running
- mysql_global_status_slave_sql_running
- mysql_global_status_seconds_behind_master
5. Grafana可视化实战
5.1 仪表板导入
推荐使用ID号为7362的官方MySQL仪表板:
- 登录Grafana -> Create -> Import
- 输入7362并加载
- 选择对应的Prometheus数据源
5.2 自定义面板技巧
制作查询QPS变化曲线:
- 新建Panel -> Time series
- 输入PromQL:
promql复制rate(mysql_global_status_questions[1m]) - 设置单位为"reqs/s"
5.3 告警规则配置
示例:检测连接数超过80%阈值
yaml复制groups:
- name: mysql.rules
rules:
- alert: MySQLHighConnections
expr: mysql_global_status_threads_connected / mysql_global_variables_max_connections > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "High MySQL connections (instance {{ $labels.instance }})"
description: "MySQL connections are at {{ $value }}% of max_connections"
6. 生产环境优化经验
6.1 采集频率权衡
根据业务特点调整scrape_interval:
- 交易系统:15-30秒
- 报表系统:1-5分钟
过高的采集频率会导致:
- Prometheus存储压力增大
- 对MySQL产生额外查询负载
6.2 指标过滤策略
在mysqld_exporter启动参数中添加:
code复制--collect.skip-collectors=engine_tokudb_status,engine_innodb_status
只收集必要指标可以降低30%以上的资源消耗。
6.3 长期存储方案
对于需要保留超过15天的监控数据:
- 使用VictoriaMetrics替代Prometheus
- 配置Prometheus远程写入到InfluxDB
- 使用Thanos实现多实例联邦查询
7. 典型问题排查指南
7.1 Exporter连接失败
错误现象:
code复制ERROR: could not connect to database server: sql: no rows in result set
排查步骤:
- 验证.my.cnf文件权限(应设为640)
- 检查MySQL用户权限
- 测试手工连接:
bash复制
mysql -u exporter -p -h 127.0.0.1
7.2 指标缺失问题
常见原因:
- 未启用对应的collector
- MySQL版本不支持某些指标
- Prometheus relabel配置错误
诊断方法:
bash复制curl http://exporter-ip:9104/metrics | grep 目标指标
7.3 性能影响评估
监控系统对MySQL的影响主要来自:
- 状态查询的CPU开销
- 监控连接占用线程数
评估方法:
sql复制SHOW PROCESSLIST;
SELECT * FROM sys.session WHERE user='exporter';
8. 高级监控场景扩展
8.1 分库分表监控
当使用分片架构时:
- 为每个分片部署独立的exporter
- 添加shard标签:
yaml复制relabel_configs: - source_labels: [__address__] target_label: shard regex: '(.*):\d+'
8.2 自定义指标采集
通过--collect.custom.query参数收集业务指标:
yaml复制collectors:
custom_query:
query: "SELECT COUNT(*) as count FROM orders WHERE status='pending'"
metrics:
- metric_name: mysql_orders_pending
value_column: count
8.3 与K8s集成
在Kubernetes中部署时:
- 使用ConfigMap存储.my.cnf
- 通过ServiceMonitor自动发现Pod
- 添加annotations实现自动监控:
yaml复制annotations: prometheus.io/scrape: "true" prometheus.io/port: "9104"
经过多个生产环境的实践验证,这套监控方案可以帮助DBA团队提前发现80%以上的潜在数据库问题。关键在于根据业务特点调整指标采集策略,并建立合理的告警阈值。
