0aa8fe6
这次没有正文改动。
这是 database/MySQL 慢查询与连接数排查.md 的改动记录。后台每次保存都会留一份快照,
这里显示的是快照之间的差异,不会混入其他文章的改动。
还没有后台修改记录。
下面是 Git 里的提交,可能包含其他文章的改动(因为一次提交会带上工作区所有变化)。
0aa8fe6
这次没有正文改动。
a0b4968
@@ -0,0 +1,74 @@ +--- +tags: [MySQL, 性能, 排障] +order: 30 +--- + +# MySQL 慢查询与连接数排查 + +## 场景 + +应用变慢、接口超时,DBA 说数据库没问题,但 `show processlist` 里一堆 `Sending data`。 + +## 前置条件 + +- 有 root 或监控权限 +- 知道业务高峰时段 +- 能改配置并重启(或动态设置) + +## 配置 + +开启慢日志(8.0 动态生效): + +```sql +SET GLOBAL slow_query_log = ON; +SET GLOBAL long_query_time = 1; +SET GLOBAL log_output = 'FILE'; +SHOW VARIABLES LIKE 'slow_query_log_file'; +``` + +排查连接: + +```sql +SHOW STATUS LIKE 'Threads_connected'; +SHOW STATUS LIKE 'Max_used_connections'; +SHOW VARIABLES LIKE 'max_connections'; +SHOW PROCESSLIST; +``` + +看谁在等锁: + +```sql +SELECT * FROM performance_schema.data_locks; +SELECT * FROM sys.innodb_lock_waits; +``` + +分析慢日志: + +```bash +mysqldumpslow -s t -t 20 /var/lib/mysql/slow.log +# 或 +pt-query-digest /var/lib/mysql/slow.log | head -60 +``` + +## 验证 + +```sql +EXPLAIN SELECT ...; -- 看是否走索引 +SHOW PROFILE FOR QUERY 1; -- 8.0 用 performance_schema +``` + +## 回滚 + +```sql +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` 要重启,别在业务高峰做。