Oamc

MySQL 慢查询与连接数排查

本页目录

场景

应用变慢、接口超时,DBA 说数据库没问题,但 show processlist 里一堆 Sending data。

前置条件

  • 有 root 或监控权限
  • 知道业务高峰时段
  • 能改配置并重启(或动态设置)

配置

开启慢日志(8.0 动态生效):

SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
SET GLOBAL log_output = 'FILE';
SHOW VARIABLES LIKE 'slow_query_log_file';

排查连接:

SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';
SHOW VARIABLES LIKE 'max_connections';
SHOW PROCESSLIST;

看谁在等锁:

SELECT * FROM performance_schema.data_locks;
SELECT * FROM sys.innodb_lock_waits;

分析慢日志:

mysqldumpslow -s t -t 20 /var/lib/mysql/slow.log
# 或
pt-query-digest /var/lib/mysql/slow.log | head -60

验证

EXPLAIN SELECT ...;          -- 看是否走索引
SHOW PROFILE FOR QUERY 1;    -- 8.0 用 performance_schema

回滚

SET GLOBAL long_query_time = 10;
SET GLOBAL slow_query_log = OFF;

坑

  • max_connections 调大不一定有用,连接多了内存和上下文切换更糟。
  • 慢日志开了但 long_query_time 还是默认 10 秒,等于没开。
  • Sending data 不代表在传数据,多数时候是在扫表。
  • 没有索引的 LIKE '%xx%' 一定全表扫。
  • 事务没提交会一直持锁,SHOW ENGINE INNODB STATUS 里能看到。
  • 改 innodb_buffer_pool_size 要重启,别在业务高峰做。