Mysql应急调优心得——杀敌一千自损八百

本文分享了MySQL短连接问题及其解决办法,包括如何杀掉空闲线程以及避免连接数过多导致的损失。同时,讨论了慢查询的性能问题,指出索引设计、SQL编写和索引选择可能导致的性能瓶颈,并预告后续文章将深入讲解调优策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

短连接问题

顾名思义,短连接就是一个连接到数据库后,执行很少的 SQL 语句就断开,下次需要的时候再重连。如果使用的是短连接,在业务高峰期的时候,就可能出现连接数突然暴涨的情况。
MySQL 建立连接的过程,成本是很高的。除了正常的网络连接三次握手外,还需要做登录权限判断和获得这个连接的数据读写权限。在数据库压力比较小的时候,这些额外的成本并不明显。但是,一旦数据库处理得慢一些,连接数就会暴涨。而一旦MySQL同时连接的数量超过连接数的最大上限,也就是max_connections这个参数,系统就会拒绝接下来的连接请求,并报错提示“Too many connections”。

解决办法:

1.杀掉那些占着连接但不工作的线程

对于那些不需要保持的连接,我们可以通过 kill connection 主动踢掉。这个行为跟事先设置 wait_timeout 的效果是一样的。设置 wait_timeout 参数表示的是,一个线程空闲 wait_timeout 这么多秒之后,就会被 MySQL 直接断开连接。
那么如果主动选择那些,不工作的线程呢。可以通过命令: show processlist 来查看。不过要注意的是,可能会是有损失的。例如有两个线程正在执行,如图所示:

在这里插入图片描述
在上面这个例子里,如果断开 session A 的连接,因为这时候 session A 还没有提交,所以 MySQL 只能按照回滚事务来处理;而断开 session B 的连接,就没什么大影响。所以,如果按照优先级来说,应该优先断开像 session B 这样的事务外空闲的连接。
但是,怎么判断哪些是事务外空闲的呢?session C 在 T 时刻之后的 30 秒执行 show processlist,看到的结果是这样的。

在这里插入图片描述

图中 id=4 和 id=5 的两个会话都是 Sleep 状态。而要看事务具体状态的话,可以查 information_schema 库的 innodb_trx 表。
在这里插入图片描述
这个结果里,trx_mysql_thread_id=4,表示 id=4 的线程还处在事务中。
因此,如果是连接数过多,你可以优先断开事务外空闲太久的连接;如果这样还不够,再考虑断开事务内空闲太久的连接。
从服务端断开连接使用的是 kill connection + id 的命令, 一个客户端处于 sleep 状态时,它的连接被服务端主动断开后,这个客户端并不会马上知道。直到客户端在发起下一个请求的时候,才会收到这样的报错“ERROR 2013 (HY000): Lost connection to MySQL server during query”。
从数据库端主动断开连接可能是有损的,尤其是有的应用端收到这个错误后,不重新连接,而是直接用这个已经不能用的句柄重试查询。这会导致从应用端看上去,“MySQL 一直没恢复”。

2.减少连接过程的消耗

有的业务代码会在短时间内先大量申请数据库连接做备用,如果现在数据库确认是被连接行为打挂了,那么一种可能的做法,是让数据库跳过权限验证阶段。跳过权限验证的方法是:重启数据库,并使用–skip-grant-tables 参数启动。这样,整个 MySQL 会跳过所有的权限验证阶段,包括连接过程和语句执行过程在内。但是,这种方法风险极高,是我特别不建议使用的方案。尤其你的库外网可访问的话,就更不能这么做了。

慢查询性能问题

在 MySQL 中,会引发性能问题的慢查询,大体有以下三种可能:
1.索引没有设计好
2.SQL语句没写好
3.MySQL选错了索引

这三种方式,在我们上线之前利用慢查询功能,就可以检测出来,逐个调优的。
具体方案我会在后序文章中详细说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值