Yihui’s Blog

如何进行MySQL性能监控?关键性能指标有哪些?

日期:2026-09-27
标签:#面试 #MySQL #数据库
难度:困难
来源:牛面 MySQL 题库
答案说明:独立整理(站内题目标记为 VIP,未读取会员答案)

一句话答案

MySQL 监控要把业务请求延迟与数据库内部等待、吞吐、资源和复制状态连起来看;单一 QPS、连接数或“复制延迟秒数”不足以解释故障。

面试口语版(约 70 秒)

“我会分四层监控。第一层是业务与 SQL:接口成功率、P95/P99、QPS/TPS、慢查询数量,以及按 SQL 摘要统计的总耗时和扫描行数。第二层是 MySQL 内部:活跃连接、正在执行的事务、锁等待和死锁、临时表与排序、缓冲池读写。第三层是主机资源:CPU、内存、磁盘延迟与吞吐、网络,避免把机器 I/O 饱和误诊为 SQL 问题。第四层是复制:接收线程、回放线程和各 worker 错误、待回放事务与读延迟。告警应按用户影响和持续时间设计,例如接口 P99 上升且锁等待同步增加,就先找长事务;如果复制回放积压,先把强一致读切回主库。监控基线要按业务峰谷比较,计数器算速率,不能仅看绝对值。”

指标与定位路径

层次重点指标典型用途
用户与应用成功率、P95/P99、超时率、连接池等待判断真实影响和发生范围
SQL语句摘要频次/总耗时/平均耗时、慢查询、扫描行数找最值得优化的语句族
并发与事务活跃线程、等待中的锁、死锁、长事务找排队和阻塞源
内存与 I/O缓冲池读请求与物理读、脏页、磁盘延迟、CPU判断缓存或存储瓶颈
复制receiver/applier 状态、worker 错误、已接收/已执行 GTID、业务读陈旧度区分接收与回放积压
flowchart TD
  A[接口 P99 上升] --> B{MySQL SQL 总耗时上升?}
  B -->|是| C[定位 SQL 摘要与计划]
  B -->|否| D[看连接池与网络]
  C --> E{锁等待增加?}
  E -->|是| F[定位长事务与阻塞链]
  E -->|否| G[看扫描、I/O 与 CPU]

例子与失败分支: 大促中 QPS 持平但下单 P99 从 100 ms 升到 3 s,活跃连接与行锁等待同步升高。此时扩连接数可能加重争锁;应先查热点商品行、事务持锁时间、重试风暴,并在应用侧做限流或排队。若是物理读和磁盘延迟同时上升,则转向索引、缓存命中和存储容量。

关键细节与常见误区

  • MySQL 8.4 可用 Performance Schema 的语句摘要、等待事件、事务和复制表辅助排查;采集时确认相关 instrumentation 已启用,并控制采样与监控查询本身的开销。
  • Threads_connected 不是“正在执行的查询数”;计数类状态值要看单位时间增量,并按实例与角色分组。
  • 缓冲池命中率高不代表没有 I/O 瓶颈:绝对物理读量、读延迟和写入刷盘仍可能过高。
  • SHOW REPLICA STATUS 的单个延迟字段在复杂拓扑或线程停滞时可能误导;查看 Performance Schema 的连接、协调器和 worker 状态,并结合业务读陈旧度验证。

面试官递进追问

1. QPS 没变但 P99 升高,你先看哪些指标来分辨排队、锁和磁盘 I/O?

参考答案: 先把接口耗时拆成连接池等待、网络往返和数据库执行,QPS 不变也可能是单次请求更重或重试占比变高。若连接池等待、Threads_running 和 CPU 运行队列同时升高,优先怀疑并发排队;若 data_lock_waits 增多,沿等待链找持锁事务及其持续时间;若缓冲池物理读速率、磁盘读写延迟或日志同步等待升高,则检查 I/O。所有指标按同一时间窗口和实例对齐,并结合最慢 SQL 摘要的参数、扫描量及计划变化。这样才能区分热点锁、查询退化和资源饱和,避免只凭 CPU 利用率或命中率下结论。

2. 连接数突然升高时,为什么不应马上把 max_connections 翻倍?

参考答案: 连接上限控制的是能接入多少会话,并不会增加 CPU、磁盘或锁的处理能力。先区分空闲连接堆积与活跃查询增长:前者检查连接泄漏、应用扩容后的总连接池配额和连接回收;后者检查慢 SQL、长事务、锁等待及重试风暴。盲目翻倍可能把应用侧排队转移到数据库内部,增加调度和内存压力,反而拖高 P99。应先限制应用并发、缩短异常事务并修复泄漏;只有实测仍有资源余量、确实是连接配额不足时,才调整上限。内存预算要覆盖实际并发下按需分配的排序、连接和临时表内存,而不是把所有缓冲都当成每连接固定预分配。

3. 从库“延迟 0 秒”却查不到刚写入数据,可能有哪些原因,如何验证?

参考答案: “延迟 0 秒”不证明刚提交的事务已在本次读取的副本生效:接收线程可能仍落后源库,只是回放已追上当前 relay log;还可能读到了另一台副本、旧的 RR 快照或应用缓存,或者存在复制过滤。先记录写事务 GTID、实际读库的 server_uuid 和复制通道,核对该 GTID 是否属于目标副本的 gtid_executed,再查 receiver/applier 状态与错误。若尚未执行,可在该副本等待目标 GTID,超时读主;若已执行,则用新事务直接查询并检查过滤与数据差异。GTID 已执行也不能排除曾跳过事务或过滤数据,最终需核对业务行。官方依据:复制状态字段。

自测与学习清单

  • 为订单接口设计一张包含用户、SQL、锁、主机和复制五层的看板。
  • 从一个“接口超时”告警画出最短排查路径,并说明每一步依据。
  • 区分计数器、速率、瞬时值和延迟分位数,避免错误聚合。

延伸阅读

参考资料

Maintained by · YihuiEdit on GitHub

Keep reading

View all posts