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配置文件,将消息队列服务修改为当前虚 ...
随机推荐
- c++并发编程实战-第4章 并发操作的同步
等待事件或等待其他条件 坐车案例 想象一种情况:假设晚上坐车外出,如何才能确保不坐过站又能使自己最轻松? 方法一:不睡觉,时刻关注自己的位置 1 #include <iostream> 2 ...
- 应用间通信(一):详解Linux进程IPC
进程之间是独立的.隔离的,使得应用程序之间绝对不可以互相"侵犯"各自的领地. 但,应用程序之间有时是需要互相通信,相互写作,才能完成相关的功能,这就不得不由操作系统介入,实现一种通 ...
- 前端预览和打印PDF的两种方式
最近工作中遇到了一个需求,就是前端选择表格中的某一条数据去请求后端接口,后端返回的是一个PDF文件的下载地址,但是需求不希望用户下载下来再去打印,而是直接预览展示,然后就能打印. 一开始按照网上的方式 ...
- Springboot笔记<2>IOC容器与组件注入
IOC容器就是具有依赖注入功能的容器,IOC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应用程序由IOC容器进行组装. 查看ioc容器中 ...
- MySQL 情节:SQL 语句的表演
本文由 ChatMoney团队出品 第一幕:解析与优化 - "翻译官与谋士" SQL 解析器是第一个上场的角色,任务就是把 SQL 请求翻译成 MySQL 能听懂的语言.就像你点餐 ...
- Controller接收前端参数
四个常用的Mapping @PutMapping: 和PostMapping作用等同,都是用来向服务器提交信息.如果是添加信息,倾向于用@PostMapping,如果是更新信息,倾向于用@PutMap ...
- 使用 SpringBoot 集成 WebService [不需要身份验证]
一.使用 JDK 自带的工具生成实体类 # 格式 wsimport -s 保存路径 -p 包路径 -encoding utf-8 wsdl文件地址 # 实例 wsimport -s d:\wsdl - ...
- UI上将BP附件放到BP结果中
1,取附件内容放到新增的字段里 METHOD get_attachment. DATA: current TYPE REF TO if_bol_bo_property_access. DATA: dr ...
- Docker命令速查
Docker命令 显示所有正在运行的docker容器 docker ps 显示所有docker容器 docker ps -a 运行容器 docker run : 运行一个容器并连接到它 docker ...
- 简单的php奥运倒计时牌
1 <?php 2 3 date_default_timezone_set ( "Asia/Shanghai" ); 4 $kaimu = mktime ( 4, 0, 0, ...