performance_schema和sys库只能观测MySQL服务端处理耗时,无法反映TCP或客户端网络真实延迟;SHOW PROCESSLIST不显示连接建立阶段卡点,因其仅展示认证后的会话,而DNS解析、TCP握手、防火墙拦截等问题发生在MySQL介入前。

MySQL 协议层本身不提供“性能追踪功能”,performance_schema 和 sys 库能观测到的连接延迟,实际是 MySQL 服务端视角的处理耗时,不是 TCP 或客户端网络栈的真实往返延迟。真要定位客户端连接慢,得绕开协议层,从下往上查。
为什么 SHOW PROCESSLIST 看不到连接建立阶段的卡点?
SHOW PROCESSLIST 只显示已成功握手、进入认证后状态的会话。如果客户端连不上或卡在 Connecting 状态,说明问题出在 TCP 连接建立(SYN/SYN-ACK)、DNS 解析、防火墙拦截、或 MySQL 的 max_connections/wait_timeout 配置上——这些阶段 MySQL 根本没机会记录。
- DNS 反向解析失败会导致连接卡顿:检查
skip_name_resolve=ON是否启用,否则 MySQL 会对每个客户端 IP 做反向 DNS 查询 - 客户端
connect_timeout设置过小(如 1 秒),而网络 RTT 波动大,就会频繁报Lost connection to MySQL server at 'connecting to initial communication packet' - MySQL 启动时未绑定正确网卡(
bind_address配置为127.0.0.1却被远程访问)也会表现为“连不上”而非“慢”
怎样用 performance_schema 抓住协议层之后的第一段耗时?
一旦连接完成认证,MySQL 就开始记录线程生命周期。关键表是 performance_schema.events_statements_history_long 和 performance_schema.events_stages_history_long,它们能反映单条语句在各个执行阶段的耗时,比如:
-
stage/sql/Waiting for query cache lock:说明查询缓存争用(建议关掉query_cache_type=OFF) -
stage/sql/Sorting result或stage/sql/Creating sort index:ORDER BY 或 GROUP BY 触发了文件排序,sort_buffer_size不足或缺少索引 -
stage/sql/Opening tables:表打开慢,可能因为table_open_cache不够,或有大量临时表未释放
执行示例:
SELECT EVENT_NAME, TIMER_WAIT/1000000000 AS time_sec, SQL_TEXT FROM performance_schema.events_statements_history_long WHERE SQL_TEXT LIKE 'SELECT %' ORDER BY TIMER_WAIT DESC LIMIT 5;
客户端真实连接延迟该用什么工具测?
别依赖 MySQL 内部指标。直接在客户端机器上做实测:
- 用
mysqladmin ping -h $HOST -P $PORT -u $USER -p --sleep=1 --count=10测端到端响应,排除应用层逻辑干扰 - 用
tcping -x 5 $HOST $PORT(或nc -zv $HOST $PORT)验证 TCP 层是否通、SYN 耗时多少 - 用
dig +short $HOST和nslookup $HOST对比 DNS 解析时间,确认是否因 DNS 导致首包延迟 - 如果用连接池(如 HikariCP),检查
connection-timeout和validation-timeout是否设得太紧,导致健康检测失败后反复重连
真正难排查的,是那些混合了 DNS 解析超时 + TCP 重传 + MySQL 认证延迟的场景。这时候 strace -e trace=connect,sendto,recvfrom -p $(pgrep mysqld) 在服务端抓系统调用,比看任何 SQL 执行计划都管用。



















