【MySQL深入详解】第05篇:MySQL监控体系——SLO驱动的可靠性工程

1 阅读7分钟

开篇引入

想象一下:你的在线商店在双十一零点准时开抢,结果数据库在高峰期"啪"地一下崩了。客服电话被打爆,老板脸色铁青,技术团队连夜排查。这场景是不是很熟悉?

问题出在哪?不是代码写得烂,不是服务器配置低,而是——你们根本没有建立有效的监控体系。没人知道数据库什么时候开始变慢,没人在意连接数悄悄爬升,更没人注意到磁盘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强调的是"主动发现潜在问题"。

被动响应的典型流程

  1. 客户投诉系统慢
  2. 团队开始排查
  3. 发现某个查询占用大量资源
  4. 紧急优化或kill查询
  5. 客户已经等了好几分钟

主动监控的流程

  1. Threads_running连续上升趋势
  2. 触发预警
  3. 自动扩容或优化
  4. 客户完全无感知

了解业务节奏

监控必须配合业务周期来设计。以下几个场景你肯定遇到过:

电商网站: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;

小结

  1. SLO是服务的北极星指标:用它定义什么叫"客户满意",而不是追求100%完美
  2. 三个核心SLI必须监控:可用性、延迟、错误率
  3. Threads_running是关键预警指标:超过CPU核心数就要警惕
  4. 平均值会掩盖问题:使用百分位数更能反映真实用户体验
  5. 监控要配合业务节奏:了解流量高峰,提前做好准备
  6. 主动监控胜于被动响应:在客户感知之前发现问题

SRE的核心思想是:测量结果,而非输出。监控不是为了展示花里胡哨的图表,而是为了回答一个简单的问题——我们的客户满意吗


上一篇【第04篇】MVCC机制揭秘——MySQL如何实现高性能并发

下一篇【第06篇】Performance Schema详解——MySQL性能诊断神器


延伸阅读

  • 《Google SRE工作手册》第1、2、5章
  • 《Implementing Service Level Objectives》——Alex Hidalgo
  • 《高性能MySQL》第3章 Performance Schema