MySQL 22 MySQL有哪些“饮鸩止渴”提高性能的方法?
有时候,在业务高峰期,生产环境的MySQL压力太大,没法正常响应,需要短期内、临时性地提升一些性能。本文就来讲讲一些临时方法,并着重说它们可能存在的风险。
短连接风暴
正常的短连接模式是连接到数据库后,执行很少的SQL语句就断开,下次需要的时候再重连。如果使用的是短连接,在业务高峰期时,可能出现连接数突然暴涨的情况。
MySQL建立连接的过程成本很高,在数据库压力比较小的时候,这些额外成本并不明显。
短连接模型存在一个风险,就是一旦数据库处理慢一些,连接数就会暴涨。max_connections参数用来控制一个MySQL实例同时存在的连接数的上限,超过这个值,系统就会拒绝接下来的连接请求并报错。对于被拒绝连接的请求来说,从业务角度看就是数据库不可用。
当机器负载较高,处理现有请求时间变长,每个连接保持的时间也更长,这时来的新连接很可能就超过数量限制。此时如果调高参数,那么系统负载可能进一步加大,大量的资源耗费在权限验证等逻辑上,结果可能更差。
这里还有两种方法,但都是有损的。
方法一:先处理掉那些占着连接但是不工作的线程
对于不需要保持的连接,可以通过kill connection主动剔除,这个行为和事先设置wait_timeout效果相同。wait_timeout参数表示线程空闲多少时间后会被MySQL直接断开连接。
在show processlist的结果里,踢掉显示为sleep的线程,可能是有损的:

在上面的流程中,如果断开session A的连接,由于事务还未提交,MySQL只能按照回滚事务来处理;如果断开session B的连接,就没有大影响。因此按照优先级来说,应该先断开像session B这样的事务外的空闲连接。
如何判断哪些是事务外空闲的呢?session C执行show processlist看到的结果为:

id=4,id=5两个会话都是sleep状态,而要看事务具体状态的话,可以查information_schema库的innodb_trx表:

trx_mysql_thread_id=4,表示id=4的线程还处在事务中。
因此,如果连接数过多,可以优先断开事务外空闲久的连接;如果还是太多,再考虑断开事务内空闲久的连接。
服务端断开连接用的是kill connection+id的命令,处于sleep状态的客户端连接被服务端主动断开后,客户端并不会马上知道,直到客户端在发起下一个请求时,才会收到报错“Lost connection to MySQL server during query"。
方法二:减少连接过程的消耗
一种可能的做法是让数据库跳过权限验证阶段,方法是重启数据库,并使用-skip-grant-tables参数启动,这样整个MySQL会跳过所有权限验证阶段,包括连接过程和语句执行过程在内。
但该方法风险极高,并不建议使用。在MySQL 8.0版本中,如果启用该参数,MySQL会默认把--skip-networking参数打开,表示这时候数据库只能被本地客户端连接,不可外网访问。
慢查询性能问题
在MySQL中,会引发性能问题的慢查询大体分为三种可能:
索引没有设计好;
SQL语句没写好;
MySQL选错索引。
接下来就具体分析这三种可能。
索引没有设计好
这种场景一般就是通过紧急创建索引来解决。在MySQL 5.6版本之后,创建索引已支持Online DDL,对于高峰期数据库被语句打挂了的情况,最高效的做法就是直接执行alter table语句。
理想情况是能在备库先执行。假设现在有主库A和备库B,该方案的大致流程为:
在备考B上执行
set sql_log_bin=off,即不写binlog,然后执行alter table去加索引;执行主备切换;
在A上执行
set sql_log_bin=off,然后执行alter table加索引。
平时变更时,应该考虑gh-ost这样的方案更为稳妥,但紧急处理时上面的方案效率最高。
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。
上面的三种情况,实际上出现最多的是前两种。为了避免这两种情况,可以通过下面的过程预先发现问题:
上线前,在测试环境打开慢查询日志,且把long_query_time设为0,确保每个语句都会被记录入慢查询日志;
在测试表里插入模拟线上的数据,做一遍回归测试;
观察日志里 每类语句的输出,特别留意Rows_examined字段是否与预期一致。
如果新增SQL语句不多,手动跑一下就可以。如果是新项目或修改了原项目的表结构设计,全量回归测试都是必要的,这是可以借助开源工具pt-query-digest。
QPS突增问题
有时候由于业务突然出现高峰,或者应用程序bug,导致某个语句的QPS突然暴涨,也可能导致MySQL压力过大,影响服务。
对于功能bug,最理想的情况是让业务把这个功能下掉,下掉一个功能,从数据库端处理的话,对于不同的背景,有不同的方法可用:
由全新业务的bug导致。假设你的DB运维是比较规范的,也就是说白名单是一个个加的。这种情况下,如果能够确定业务方会下掉这个功能,只是时间上没那么快,那么就可以从数据库端直接把白名单去掉;
如果功能使用的是单独的数据库用户,可以删除这个用户然后断开现有连接;
如果新增功能跟主体功能部署在一起,只能通过处理语句来限制,如把压力最大的SQL语句直接重写成select 1。这个操作风险很高,可能存在两个副作用:
如果别的功能也用到了这个SQL语句模板,会有误伤;
很多业务不是只靠一个语句完成,如果单独把这个语句重写,可能导致后面的业务逻辑一起失败。
MySQL 22 MySQL有哪些“饮鸩止渴”提高性能的方法?的更多相关文章
- 22 mysql有那些”饮鸩止渴”提高性能的方法?
22 mysql有那些”饮鸩止渴”提高性能的方法? 正常的短连接模式是连接到数据库后,执行很少的SQL语句就断开,下次需要的时候再重新连接.如果使用的是短连接,在业务高峰期的时候,就可能出现连接数突然 ...
- 《Mysql - 在Mysql服务出现瓶颈时,有哪些“饮鸩止渴”提高性能的方法?》
一:情景 - 业务高峰期,生产环境的 MySQL 压力太大,没法正常响应,需要短期内.临时性地提升一些性能. - 在业务高发时候,Mysql 服务压力过大,导致业务受损, 用户的开发负责人说,不管你用 ...
- 22 | MySQL有哪些“饮鸩止渴”提高性能的方法?
不知道你在实际运维过程中有没有碰到这样的情景:业务高峰期,生产环境的MySQL压力太大,没法正常响应,需要短期内.临时性地提升一些性能. 我以前做业务护航的时候,就偶尔会碰上这种场景.用户的开发负责人 ...
- mysql用find_in_set代替like搜索提高性能
mysql用find_in_set代替like搜索提高性能 <pre>SELECT * from mobantestinfo1 where find_in_set('33',info2); ...
- [日常工作]非Windows Server 系统远程经常断以及提高性能的方法
1. 公司内有不少windows xp windows 7 这样的操作系统的机器在机房里面用来跑自动化脚本或者是其他用处. 经常有人反馈机器过一段时间连不上, 其实这一点是一个非常小的地方 很多机器上 ...
- mysql数据库以加索引方式提高性能
数据库查询速率慢的情况下可以给对应的表加上对应的索引,能够有效的提高查询效率,mysql数据库添加索引的SQL入下: ALTER TABLE `table_name` ADD INDEX index_ ...
- Cocos2d-X中提高性能的方法
1)内存使用效率: 使用大纹理 场景切换时,要尽量使用replaceScene 2)用好缓存: CCTextureCache(纹理缓存) CCSpriteFrameCache(精灵帧缓存) CC ...
- CSS优化,提高性能的方法有哪些?
1,首推的是合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢. 2,减少css嵌套,最好不要套三层以上. 3,不要在ID选择器前面进行嵌套,ID本 ...
- 如果要做优化,CSS提高性能的方法有哪些?
一.前言 每一个网页都离不开css,但是很多人又认为,css主要是用来完成页面布局的,像一些细节或者优化,就不需要怎么考虑,实际上这种想法是不正确的 作为页面渲染和内容展现的重要环节,css影响着用户 ...
- [日常工作]GS使用消息队列进行凭证实时记账 提高性能配置方法
1. 安装消息队列服务 使用平台技术部的一键安装工具,安装. 自带jdk以及activeMQ 自动注册服务. 比较方便. 2. 修改/gsp/config下面的MQ配置文件,将消息队列服务修改为当前虚 ...
随机推荐
- k8s二进制安装
各节点安装docker yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-rep ...
- 实现远程磁盘:像访问自己的电脑硬盘一样访问对方的电脑硬盘 (附Demo源码)
在现实场景中,远程桌面的功能大家已经用得很多了,而在某些场景下,我们需要使用类似的远程磁盘功能,这样能非常方便地操作对方电脑磁盘的目录.以及传送文件.那么,这样的远程磁盘功能要怎么实现了? 这次我们将 ...
- 自实现模态对话框-DoModal函数
参考CDialog::DoModal函数的实现方式,自己实现了模态框相关功能. ModalBase.h头文件 1 #include <afxwin.h> 2 3 #define ID_NU ...
- 操作系统:设备I/O -- 设备如何处理内核I/O包
上一讲实现了建立设备的接口,相当于制定了部门的相关法规,只要遵循这些法规就能建立一个部门.一个部门的职责不难确定,它应该能对上级下发的任务作出响应,并完成相关工作,而这对应到设备,就是如何处理内核的I ...
- LocalSend 编译全过程深度讲解,解决手机与电脑互传文件痛点
localsend编译 LocalSend 是一款开源.跨平台的 本地网络文件传输工具,旨在通过局域网实现设备间快速.安全的文件共享,无需依赖互联网或第三方服务器.它支持 Windows.macOS. ...
- 使用IntelliJ IDEA 比对文件内容差异
摘要:使用IntelliJ IDEA 比对文件内容差异部分,迅速定位修改点. 在敲代码的过程中,经常需要比较两个代码文件的内容差异,很多人会去网上找文件比较工具来处理,其实 IntelliJ ID ...
- 如何实现RAG与MCP集成
1.概述 在人工智能的创新浪潮中,检索增强生成(RAG)技术以其高效调用外部知识.提升生成内容准确性的能力备受瞩目,而模型上下文协议(MCP)则为不同模型间的交互与协同提供了标准框架.当 RAG 的知 ...
- Springboot笔记<1>版本控制器、场景启动器与自动配置原理
springboot版本控制器 SpringBoot应用的pom.xml中引入了一个父项目parent:spring-boot-starter-parent,spring-boot-starter-p ...
- Java生成二维码带LOGO
前言 Java后端生成二维码 参考文章 使用Java生成二维码图片(亲测) Reborn_YY使用Java生成二维码图片 图标素材库 Java后台生成图片,前台实现图片下载 jar 保持和spring ...
- 开源DeepWiki 企业老项目救星:自动生成文档+AI问答,告别遗留代码维护噩梦
企业痛点一击即中 你是否还在为这些问题头疼: 核心业务系统缺乏文档,新人上手困难 老员工离职带走关键代码知识 系统升级维护成本居高不下 业务逻辑复杂,代码理解困难 OpenDeepWiki最新版本专为 ...