1. 引子
本章讨论的是业务高峰期临时地让 MySQL 提升性能的方法
2. 短连接风暴
短连接:连接到数据库后,执行很少的 SQL 语句就断开,下次需要的时候再重连。
连接数据库的过程需要三次握手+MySQL 登录权限判断,连接成本高
MySQL 有一个参数:max_connections,控制最大连接数
业务高峰期 MySQL 不可用可能的原因:部分短连接在高峰期机器负载高,请求和连接时间变长,导致过多的连接堆积,因此连接数在高峰期容易达到max_connections。这种情况如果提高max_connections,让更多的连接都可以进来,那么系统的负载可能会进一步加大,适得其反,因此并不建议。
3. 解决方案
两种有损的解决方案
3.1 先处理掉那些占着连接但是不工作的线程
可以处理掉显示为 sleep 的线程

事务 A:插入操作,此时还没提交,如果在 T+30 kill 掉只能回滚事务 A
事务 B:查询操作,且是事务外操作,在 T+30 kill 掉事务 B 是无损的。
因此:优先断开像 session B 这样的事务外空闲的连接。如果这样还不够,再考虑断开事务内空闲太久的连接。
注意:从服务端断开连接使用的是 kill connection + id 的命令, 一个客户端处于 sleep 状态时,它的连接被服务端主动断开后,这个客户端并不会马上知道。直到客户端在发起下一个请求的时候,才会收到这样的报错“ERROR 2013 (HY000): Lost connection to MySQL server during query”。
3.2 减少连接过程的消耗
有的业务代码会在短时间内先大量申请数据库连接做备用,如果现在数据库确认是被连接行为打挂了,那么一种可能的做法,是让数据库跳过权限验证阶段。
如果启用–skip-grant-tables 参数即可跳过权限验证,但是风险很高。
4. 慢查询问题
减少连接时间的还可以优化慢 SQL
接下来逐步分析造成慢 SQL 的三种原因
4.1 索引没设计好
紧急执行 alter table 增加索引,流程如下:
理想情况是在备库先执行
-
在备库 B 上执行 set sql_log_bin=off,也就是不写 binlog,然后执行 alter table 语句加上索引;
-
执行主备切换;
-
这时候主库是 B,备库是 A。在 A 上执行 set sql_log_bin=off,然后执行 alter table 语句加上索引。
4.2 SQL 语句没写好
例如:select * from t where id + 1 = 10000就不会走索引(前面讲过)
4.3 SQL 语句选错索引
因此可以 force index 让 SQL 语句强制使用索引
5. QPS 突增问题
场景:业务突然出现高峰,或者应用程序 bug,导致某个语句的 QPS 突然暴涨,也可能导致 MySQL 压力过大,影响服务
解决方案:
-
业务方恢复功能
-
数据库端的处理:
暂时将对应业务方从数据库白名单去掉,如果是新业务使用的是单独的数据库用户,可以将这个用户删掉。如果是新增的功能跟主体功能是部署在一起,只能重写 SQL 成 select 1 返回。
这里是程序员 Joey,如果本期内容对您有帮助,欢迎关注、点赞、评论和分享!
MySQL性能急救方法

被折叠的 条评论
为什么被折叠?



