临时提升MySQL性能的方法

业务高峰期,生产环境的MySQL压力太大,没法正常响应,需要短期内、临时性地提升一些性能。

大概有哪些情况呢?

短连接风暴

正常的短连接模式就是连接到数据库后,执行很少的SQL语句就断开,下次需要的时候再重连。如果使用的是短连接,在业务高峰期的时候,就可能出现连接数突然暴涨的情况。

短连接模型存在一个风险,就是一旦数据库处理得慢一些,连接数就会暴涨。

先处理掉那些占着连接但是不工作的线程

max_connections的计算,不是看谁在running,是只要连着就占用一个计数位置。对于那些不需要保持的连接,我们可以通过kill connection主动踢掉。这个行为跟事先设置wait_timeout的效果是一样的。设置wait_timeout参数表示的是,一个线程空闲wait_timeout这么多秒之后,就会被MySQL直接断开连接。

需要注意,在show processlist的结果里,踢掉显示为sleep的线程,可能是有损的,因为有些线程还处于事务内,踢掉这种类型的线程会导致该事务回滚。

因此,如果是连接数过多,你可以优先断开事务外空闲太久的连接;如果这样还不够,再考虑断开事务内空闲太久的连接。

客户端应该做好连接断开重连的操作。

减少连接过程的消耗

有的业务代码会在短时间内先大量申请数据库连接做备用,如果现在数据库确认是被连接行为打挂了,那么一种可能的做法,是让数据库跳过权限验证阶段。

跳过权限验证的方法是:重启数据库,并使用–skip-grant-tables参数启动。这样,整个MySQL会跳过所有的权限验证阶段,包括连接过程和语句执行过程在内。

但是,风险极高,是特别不建议使用的方案。尤其你的库外网可访问的话,就更不能这么做了。

在MySQL 8.0版本里,如果你启用–skip-grant-tables参数,MySQL会默认把 --skip-networking参数打开,表示这时候数据库只能被本地的客户端连接。可见,MySQL官方对skip-grant-tables这个参数的安全问题也很重视。

慢查询性能问题

在MySQL中,会引发性能问题的慢查询,大体有以下三种可能:

索引没有设计好

这种场景一般就是通过紧急创建索引来解决。

SQL语句没写好

可以通过改写SQL语句来处理。MySQL 5.7提供了query_rewrite功能,可以把输入的一种语句改写成另外一种模式。

比如,语句被错误地写成了 select * from t where id + 1 = 10000,你可以通过下面的方式,增加一个语句改写规则。

mysql> insert into query_rewrite.rewrite_rules(pattern, replacement, pattern_database) values ("select * from t where id + 1 = ?", "select * from t where id = ? - 1", "db1");
call query_rewrite.flush_rewrite_rules();

这里,call query_rewrite.flush_rewrite_rules()这个存储过程,是让插入的新规则生效,也就是我们说的“查询重写”。

MySQL选错了索引

应急方案就是给这个语句加上force index。

同样地,使用查询重写功能,给原来的语句加上force index,也可以解决这个问题。

本文作者: chenishr

本文标题:《临时提升MySQL性能的方法》

本文地址: http://blog.chenishr.com/?p=797

©版权所有,除非注明, 永在路上文章均为原创,转载请以链接形式注明出处和作者细信息。

发表评论

电子邮件地址不会被公开。 必填项已用*标注