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要重启,别在业务高峰做。