开篇引入
想象一下:你的在线商店在双十一零点准时开抢,结果数据库在高峰期"啪"地一下崩了。客服电话被打爆,老板脸色铁青,技术团队连夜排查。这场景是不是很熟悉?
问题出在哪?不是代码写得烂,不是服务器配置低,而是——你们根本没有建立有效的监控体系。没人知道数据库什么时候开始变慢,没人在意连接数悄悄爬升,更没人注意到磁盘I/O早就亮起了红灯。
传统监控是"事后诸葛亮",SRE驱动的监控是"防患于未然"。《高性能MySQL》第2章的核心思想就是:用SLO定义什么叫"客户满意",用数据说话,让监控真正服务于业务。
SLO三兄弟:SLI、SLO、SLA
这三个概念是SRE的基石,很多DBA搞不清楚它们之间的区别,我用大白话解释一下。
SLI(Sevice Level Indicator,服务水平指标)——回答"怎么衡量客户是否满意"。比如:数据库响应时间、查询成功率、服务可用时间。SLI是从用户视角看的,代表一个健康的系统应该是什么样。
SLO(Service Level Objective,服务水平目标)——回答"客户能接受的最低标准是什么"。比如:99.5%的查询在200毫秒内完成,每月可用时间不少于99.9%。SLO是你给自己定的目标值,是团队的"及格线"。
SLA(Service Level Agreement,服务水平协议)——回答"达不到标准会怎样"。SLA是和付费客户签的协议,达不到要赔钱的那种。划重点:SLA是可选的,不是每个系统都必须有。
-- 好的SLI+SLO定义示例
-- "99.5%的数据库请求在200毫秒内正常执行"
-- SLI: 数据库请求响应时间
-- SLO: 99.5%请求在200ms内完成
很多团队一开始就把SLO设成100%,这是灾难的开始。3个9的可用性意味着什么?一年有8.76小时可以宕机,转换到一周只有10分钟。你真的能达到吗?
| 可用性等级 | 年停机时间 | 周停机时间 | 实际体验 |
|---|---|---|---|
| 99% | 3.65天 | 1.68小时 | "经常维护" |
| 99.5% | 1.83天 | 50分钟 | "还行" |
| 99.9% | 8.76小时 | 10分钟 | "挺好" |
| 99.99% | 52分钟 | 1分钟 | "优秀" |
MySQL监控的三大核心指标
对于MySQL数据库,有三个SLI是必须要监控的:
1. 可用性(Availability)
可用性不是简单地说"服务能不能连接",而是"能不能无错误地响应客户请求"。
-- 验证MySQL可用性的几种方式
-- 方式1:简单连通性检查(不验证存储层)
SELECT 1;
-- 方式2:验证数据访问
SELECT COUNT(*) FROM information_schema.tables;
-- 方式3:验证写入能力(更接近真实业务)
START TRANSACTION;
INSERT INTO test_health_check (id, check_time) VALUES (1, NOW());
COMMIT;
还有一个关键指标:Threads_running。这个状态变量跟踪当前正在运行的查询数量。当它快速增长且没有下降迹象时,说明查询堆积,服务器可能即将不稳定。
-- 监控Threads_running
SHOW STATUS LIKE 'Threads_running';
-- 如果超过CPU核心数,可能处于不稳定状态
-- 需要设置告警
2. 查询延迟(Latency)
MySQL 8.0提供了丰富的延迟跟踪功能,但要注意:直接从数据库跟踪的延迟≠用户感知的延迟。现代分布式架构中,应用层、网络层的延迟都要考虑进去。
-- 使用Performance Schema跟踪查询延迟
SELECT
DIGEST_TEXT AS query,
COUNT_STAR AS executions,
SUM_TIMER_WAIT/1000000000000 AS total_seconds,
AVG_TIMER_WAIT/1000000000000 AS avg_seconds,
MAX_TIMER_WAIT/1000000000000 AS max_seconds
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;
3. 错误率(Error Rate)
不是所有错误都需要立即处理,有些只是"噪声"。
-- 需要关注的错误信号
-- Lock wait timeout增加 → 可能是行级锁争用扩大
-- Aborted connections突增 → 可能是访问层问题
-- too many connections → 连接数超限,影响客户
-- 查看连接错误统计
SHOW STATUS LIKE 'Connection_errors%';
SHOW STATUS LIKE 'Aborted%';
有些错误一旦出现就必须处理:
- read-only模式:可能是副本被误当成主库,或者配置错误
- cannot create new thread:内存耗尽的信号
主动监控 vs 被动响应
传统的监控是"等报警再去查",SRE强调的是"主动发现潜在问题"。
被动响应的典型流程:
- 客户投诉系统慢
- 团队开始排查
- 发现某个查询占用大量资源
- 紧急优化或kill查询
- 客户已经等了好几分钟
主动监控的流程:
- Threads_running连续上升趋势
- 触发预警
- 自动扩容或优化
- 客户完全无感知
了解业务节奏
监控必须配合业务周期来设计。以下几个场景你肯定遇到过:
电商网站:11月下旬到年底,销量呈数量级增长。如果数据库没准备好,峰值流量会直接打垮系统。
HR软件:美国11月的"开放登记"期间,员工集中选择福利,流量激增。
在线鲜花:情人节的订单量是平时的几十倍。
了解这些业务节奏,才能合理设定SLO,在高峰前做好准备。
监控工具选型
商业选项:SolarWinds数据库性能管理工具,自动化程度高,非技术人员也能理解。
开源选项:Percona监控和管理工具(PMM)是成熟的选择,客户端/服务器架构,仪表盘设计来自社区多年经验。
自建方案:将慢查询日志和Performance Schema输出发送到集中位置,用pt-query-digest分析。缺点是响应慢,可能在问题发生后才能发现。
度量长期性能
监控不能只看平均值。用Graphite这类工具,默认会将长期数据整合为平均值——这是大问题!
-- 查看平均响应时间(可能被平滑处理)
SELECT AVG(TIMER_WAIT)/1000000000000 FROM performance_schema.events_statements_history;
-- 更准确的方式:使用百分位数
-- 95百分位意味着95%的请求比这个值快
-- 这更接近用户真实体验
百分位监控示例:
- 50百分位(Median):中间用户的体验
- 95百分位:大多数用户的体验
- 99百分位:最差的那1%,需要关注是否影响核心功能
用SLO指导架构演进
当业务增长时,保持相同的SLO会越来越难。通过监控数据,你可以找到需要分库分表的时机:
-- 监控数据增长趋势
SELECT
table_schema,
table_name,
ROUND(data_length / 1024 / 1024, 2) AS data_mb,
ROUND(index_length / 1024 / 1024, 2) AS index_mb,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_mb
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
ORDER BY (data_length + index_length) DESC
LIMIT 20;
小结
- SLO是服务的北极星指标:用它定义什么叫"客户满意",而不是追求100%完美
- 三个核心SLI必须监控:可用性、延迟、错误率
- Threads_running是关键预警指标:超过CPU核心数就要警惕
- 平均值会掩盖问题:使用百分位数更能反映真实用户体验
- 监控要配合业务节奏:了解流量高峰,提前做好准备
- 主动监控胜于被动响应:在客户感知之前发现问题
SRE的核心思想是:测量结果,而非输出。监控不是为了展示花里胡哨的图表,而是为了回答一个简单的问题——我们的客户满意吗?
延伸阅读
- 《Google SRE工作手册》第1、2、5章
- 《Implementing Service Level Objectives》——Alex Hidalgo
- 《高性能MySQL》第3章 Performance Schema