现象: 在压测过程中发现接口返回数据非常慢,甚至超时,页面加载不出数据
问题定位:如果有慢查询怎么恢复?
1.查看服务日志,打印连接数据库超时,接口返回超时
- 查看数据库所在节点cpu占用很高
- 使用select CONCAT('kill',id,',') from information_schema.processlist where Command != 'Sleep' order by Time desc;按照查询时间从高到低查看当前数据库查询线程,找到耗时较久的查询线程,也可以加上Time字段看下当前数据库查询最大耗时多少
下图是processlist 的全字段,显示当前数据库存在的线程
说明 使用CONCAT('kill',id,',')是为了查询结果更方便的看出线程id,否则会连在一起,区分不来
- 使用select concat('kill',id,',') from informatino_schema.processlist where command != 'sleep' and Time >60 order by Time desc;
查询出当前DB查询耗时大于60秒的线程
5. sql执行kill {线程id}杀掉耗时就的线程,稍等一会,db查询会正常,查看业务是否恢复
当前系统压测时发现有慢查询,怎么确定系统慢查询的语句是什么?
- 数据库打开慢查询开关 set global slow_query_log ='ON'; 也可以在my.ini文件进行配置,永久生效
- 通过SHOW VARIABLES LIKE '%slow_query_log%'; 可以查看慢查询日志开关及日志文件
- 设置慢查询的超时时间,客户端重新连接db set global long_query_time =3 (设置慢查询的阈值为3s)
- 查询设置的慢查询超时是否生效show variables like ‘%long_query_time%’;
- 查看慢查询日志,在日志中即可看到慢查询的sql语句
使用mysqldumpslow 工具分析慢查询日志
# 得到返回记录集最多的10个SQL mysqldumpslow -s r -t 10/var/lib/mysql/slow.log
# 得到访问次数最多的10个SQL mysqldumpslow -s c -t 10/var/lib/mysql/slow.log
已知某条sql语句可能会有慢查询,怎么确定这个sql的问题?
1.客户端执行这条语句时在前面加 explain 关键字,即可看到这个sql语句的访问类型,如果是ALL,证明是硬盘表逐行遍历查询,效率很低,如果是ref指按索引遍历,rows执行过程遍历了表的多少行,如果大于1W那么执行速度肯定会慢,要确定是否增加了表索引,查询语句是否用到了索引(索引是否失效)
为什么会出现慢查询?
- 表数据量大,大于10W条,表没有索引
- sql语句是简单查询,查询条件简单
- 查询线程出现了死锁
- 内存不足