dreamweaver动态网站开发与设计教程内容/国外域名注册网站
MySQL的“饮鸩止渴”提高性能的方法
HI,我是阿昌
,今天学习记录的是关于MySQL的“饮鸩止渴”提高性能的方法
的内容。
不知道在实际运维过程中有没有碰到这样的情景:
业务高峰期,生产环境的 MySQL 压力太大,没法正常响应,需要短期内、临时性地提升一些性能。以前做业务护航的时候,就偶尔会碰上这种场景。
用户的开发负责人说,不管用什么方案,让业务先跑起来再说。但,如果是无损方案的话,肯定不需要等到这个时候才上场。
一、短连接风暴
正常的短连接模式就是连接到数据库后,执行很少的 SQL 语句就断开,下次需要的时候再重连。
如果使用的是短连接,在业务高峰期的时候,就可能出现连接数突然暴涨
的情况。
在基础架构中说过,MySQL 建立连接的过程,成本是很高的。
- 除了
正常的网络连接三次握手
外 - 还需要做
登录权限判断
- 获得这个
连接的数据读写权限
。
在数据库压力比较小的时候,这些额外的成本并不明显。
但是,短连接模型存在一个风险,就是一旦数据库处理得慢一些,连接数就会暴涨。
max_connections 参数,用来控制一个 MySQL 实例同时存在的连接数的上限,超过这个值,系统就会拒绝接下来的连接请求,并报错提示“Too many connections
”。
对于被拒绝连接的请求来说,从业务角度看就是数据库不可用。在机器负载比较高的时候,处理现有请求的时间变长,每个连接保持的时间也更长。这时,再有新建连接的话,就可能会超过 max_connections 的限制。碰到这种情况时,一个比较自然的想法,就是调高 max_connections 的值。但这样做是有风险的。
因为设计 max_connections 这个参数的目的是想保护 MySQL
,如果把它改得太大,让更多的连接都可以进来,那么系统的负载可能会进一步加大,大量的资源耗费在权限验证等逻辑上,结果可能是适得其反,已经连接的线程拿不到 CPU 资源去执行业务的 SQL 请求。
那么这种情况下,还有没有别的建议呢?
这里还有两种方法,但要注意,这些方法都是有损的。
第一种方法:先处理掉那些占着连接但是不工作的线程。
max_connections 的计算,不是看谁在 running,是只要连着就占用一个计数位置。
对于那些不需要保持的连接,可以通过 kill connection 主动踢掉
。这个行为跟事先设置 wait_timeout 的效果是一样的。
设置 wait_timeout 参数表示的是,一个线程空闲 wait_timeout 这么多秒之后,就会被 MySQL 直接断开连接。但是需要注意,在 show processlist
的结果里,踢掉显示为 sleep 的线程,可能是有损的。
来看下面这个例子。
在上面这个例子里,如果断开 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 一直没恢复”。
可能觉得这是一个冷笑话,但实际上碰到过不下 10 次。
所以,如果是一个支持业务的 DBA,不要假设所有的应用代码都会被正确地处理。
即使只是一个断开连接的操作,也要确保通知到业务开发团队。
第二种方法:减少连接过程的消耗。
有的业务代码会在短时间内先大量申请数据库连接做备用
,如果现在数据库确认是被连接行为打挂了,那么一种可能的做法,是让数据库跳过权限验证阶段
。
跳过权限验证
的方法是:重启数据库,并使用–skip-grant-tables 参数启动。
这样,整个 MySQL 会跳过所有的权限验证阶段,包括连接过程和语句执行过程在内。但是,这种方法特别符合标题里说的“饮鸩止渴”,风险极高,是特别不建议使用的方案。尤其库外网可访问的话,就更不能这么做了。
在 MySQL 8.0 版本
里,如果启用–skip-grant-tables 参数
,MySQL 会默认把 --skip-networking 参数
打开,表示这时候数据库只能被本地的客户端连接
。可见,MySQL 官方对 skip-grant-tables 这个参数的安全问题也很重视。
除了短连接数暴增可能会带来性能问题外,实际上,在线上碰到更多的是查询或者更新语句导致的性能问题。其中,查询问题比较典型
的有两类:
- 一类是由新出现的
慢查询
导致的 - 一类是由
QPS(每秒查询数)突增
导致的。
二、慢查询性能问题
在 MySQL 中,会引发性能问题的慢查询,大体有以下三种可能:
索引
没有设计好;- SQL 语句
没写好
; - MySQL
选错了索引
。
1、索引没有设计好
导致慢查询的第一种可能是,索引没有设计好。
这种场景一般就是通过紧急创建索引来解决。MySQL 5.6 版本以后,创建索引都支持 Online DDL
了,对于那种高峰期数据库已经被这个语句打挂
了的情况,最高效的做法就是直接执行 alter table 语句
。比较理想的是能够在备库先执行。
假设现在的服务是一主一备
,主库 A、备库 B,这个方案的大致流程是这样的:
- 在备库 B 上执行 set sql_log_bin=off,也就是不写 binlog,然后执行 alter table 语句加上索引;
- 执行主备切换;
- 这时候主库是 B,备库是 A。在 A 上执行 set sql_log_bin=off,然后执行 alter table 语句加上索引。
这是一个“古老”的 DDL 方案。平时在做变更的时候,应该考虑类似 gh-ost
这样的方案,更加稳妥。但是在需要紧急处理时,上面这个方案的效率是最高的。
2、语句没写好
导致慢查询的第二种可能是,语句没写好。
比如,犯了在只查一行的语句,也执行这么慢?中提到的那些错误,导致语句没有使用上索引
。这时,可以通过改写 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()
这个存储过程
,是让插入的新规则生效,也就是说的“查询重写
”。
可以用图 4 中的方法来确认改写规则是否生效。
3、选错了索引
在MySQL 为什么有时候会选错索引中提到的情况,MySQL 选错了索引
。
这时候,应急方案就是给这个语句加上 force index
。同样地,使用查询重写功能
,给原来的语句加上 force index,也可以解决这个问题。
由慢查询导致性能问题的三种可能情况,实际上出现最多的是前两种,即:索引没设计好和语句没写好。而这两种情况,恰恰是完全可以避免的。
比如,通过下面这个过程,可以预先发现问题
。
- 上线前,在测试环境,把
慢查询日志(slow log)
打开,并且把long_query_time 设置成 0
,确保每个语句都会被记录入慢查询日志; - 在测试表里插入模拟线上的数据,做一遍
回归测试
; - 观察慢查询日志里每类语句的输出,特别留意
Rows_examined 字段是否与预期一致
。
不要吝啬这段花在上线前的“额外”时间,因为这会帮你省下很多故障复盘的时间。如果新增的 SQL 语句不多,手动跑一下就可以。而如果是新项目的话,或者是修改了原有项目的 表结构设计,全量回归测试都是必要的。这时候,需要工具帮你检查所有的 SQL 语句的返回结果
。比如,可以使用开源工具 pt-query-digest
三、QPS 突增问题
有时候由于业务突然出现高峰,或者应用程序 bug,导致某个语句的 QPS 突然暴涨
,也可能导致 MySQL 压力过大,影响服务。一类情况,是由一个新功能的 bug 导致
的。
当然,最理想的情况是让业务把这个功能下掉
,服务自然就会恢复。而下掉一个功能,如果从数据库端处理的话,对应于不同的背景,有不同的方法可用。
- 一种是由
全新业务的 bug 导致的
。假设 DB 运维是比较规范的,也就是说白名单是一个个加的。这种情况下,如果能够确定业务方会下掉这个功能,只是时间上没那么快,那么就可以从数据库端直接把白名单去掉。 - 如果这个
新功能使用的是单独的数据库用户
,可以用管理员账号把这个用户删掉,然后断开现有连接。这样,这个新功能的连接不成功,由它引发的 QPS 就会变成 0。 - 如果这个新增的功能跟主体功能是部署在一起的,那么只能通过
处理语句来限制
。这时,我们可以使用上面提到的查询重写功能,把压力最大的 SQL 语句直接重写成"select 1"返回。当然,这个操作的风险很高,需要特别细致。
它可能存在两个副作用:
- 如果别的功能里面也用到了这个
SQL 语句模板,会有误伤
; - 很多业务并不是靠这一个语句就能完成逻辑的,所以如果单独把这一个语句
以 select 1 的结果返回
的话,可能会导致后面的业务逻辑一起失败
。
所以,方案 3 是用于止血
的,跟前面提到的去掉权限验证一样,应该是所有选项里优先级最低的一个方案。同时你会发现,其实方案 1 和 2 都要依赖于规范的运维体系:虚拟化、白名单机制、业务账号分离。由此可见,更多的准备,往往意味着更稳定的系统。
四、总结
以业务高峰期的性能问题为背景,介绍了一些紧急处理的手段
。
这些处理手段中,既包括了粗暴地拒绝连接和断开连接,也有通过重写语句来绕过一些坑的方法;既有临时的高危方案,也有未雨绸缪的、相对安全的预案。
在实际开发中,也要尽量避免一些低效
的方法,比如避免大量地使用短连接
。
同时,如果做业务开发的话,要知道,连接异常断开是常有的事,代码里要有正确地重连并重试的机制。
DBA 虽然可以通过语句重写
来暂时处理问题,但是这本身是一个风险高的操作,做好 SQL 审计
可以减少需要这类操作的机会。
其实,可以看得出来,在文章中提到的解决方法主要集中在 server 层
。
是否碰到过,在业务高峰期需要临时救火的场景?又是怎么处理的呢?
主从切换时遇到的问题,主从切换前主库要改为只读,设置只读后,show master status发现binlog一直在变化,当时应用没断开。
主库并不是其他库的从库,怎么搞的呢?
检查业务用户权限发现拥有super权限,查看授权语句原来是grant all on . to user,这里要说的是*.* 权限就太大了,而且这个也很容易被误解,需要特别注意。
对的,readonly对super无效;
一方面是尽量不要给业务super
一方面你做完readonly还会去确认binlog有没有变,这个意识很好哦
相关文章:

Day886.MySQL的“饮鸩止渴”提高性能的方法 -MySQL实战
MySQL的“饮鸩止渴”提高性能的方法 HI,我是阿昌,今天学习记录的是关于MySQL的“饮鸩止渴”提高性能的方法的内容。 不知道在实际运维过程中有没有碰到这样的情景: 业务高峰期,生产环境的 MySQL 压力太大,没法正常响…...

08- 数据升维 (PolynomialFeatures) (机器学习)
在做数据升维的时候,最常见的手段就是将已知维度进行相乘(或者自乘)来构建新的维度 使用 np.concatenate()进行简单的,幂次合并,注意数据合并的方向axis 1 数据可视化时,注意切片,因为数据升维…...

2023备战金三银四,Python自动化软件测试面试宝典合集(二)
马上就又到了程序员们躁动不安,蠢蠢欲动的季节~这不,金三银四已然到了家门口,元宵节一过后台就有不少人问我:现在外边大厂面试都问啥想去大厂又怕面试挂面试应该怎么准备测试开发前景如何面试,一个程序员成长之路永恒绕…...

笔试题-2023-紫光展锐-数字芯片设计【纯净题目版】
回到首页:2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录 推荐内容:数字IC设计学习比较实用的资料推荐 题目背景 笔试时间:2022.08.24应聘岗位:数字芯片设计工程师笔试时长:90min笔试平台:nowcoder牛客网题目类型:单选题(18道)、不定项选择题(22道)题目评…...

WordPress网站日主题Ri主题RiProV2主题开启了验证码登录但是验证码配置不对结果退出登录后进不去管理端了
背景 WordPress网站日主题Ri主题RiProV2主题开启了验证码登录但是验证码配置不对结果退出登录后进不去管理端了;开启了腾讯云验证码防火墙但APPID,APPSecret没配置,结果在退出登录后,由于验证码验证失败管理端进不去了 提示如下:...

自动驾驶感知——毫米波雷达
文章目录1. 雷达的基本概念1.1 毫米波雷达分类1.2 信息的传输1.3 毫米波雷达的信号频段1.4 毫米波雷达工作原理1.4.1 毫米波雷达测速测距的数学原理1.4.2 毫米波雷达测角度的数学原理1.4.3 硬件接口1.4.4 关键零部件1.4.5 数据的协议与格式1.5 车载毫米波雷达的重要参数1.6 车载…...

取电芯片全协议都可兼容
乐得瑞PD协议芯片/PD取电芯片/PD受电端协议芯片 支持5/9/12/15/20v定制 1、概述 LDR6328S 是乐得瑞科技有限公司开发的一款兼容 USB PD、QC 和 AFC 协议的 Sink 控制器。 LDR6328S 从支持 USB PD、QC 和 AFC 协议的适配器取电,然后供电给设备。比如可以配置适配器输…...

自己总结优化代码写法
jdk1.7新特性详解 开发期间略知jdk1.7的一些特性,没有真正的一个一个得展开研究,而是需要说明再去查,导致最整个新特性不是特别的清楚,这种情况以后得需要改变了,否则就会变成代码的奴隶。现在正好有时间可以细细的研…...

Java体系最强干货分享—挑战40天准备Java面试,最快拿到offer!
如何准备java面试,顺利上岸大厂java岗位? 主攻Java的人越来越多,导致行业越来越卷,最开始敲个“hello world”都能进大厂,现在,八股、全家桶、算法等等面试题横行,卷到极致!就拿今年…...

云计算|OpenStack|错误记录和解决方案(不定时更新)
前言: openstack的部署和使用是难度比较大的,难免会出现各种各样的问题,因此,本文将把一些在部署和使用openstack社区版时出现的错误做一个记录,并就每一个错误分析和解决问题。(尽量记录比较经典的错误&a…...

项目实战-NewFixedThreadPool线程池
目录 什么是线程池 线程池的类型 1.CachedThreadPool 2.FixedThreadPool 3.ScheduledThreadPool 4.SingleThreadPool 5.newWorkStealingPool 线程池的好处 1、线程池的重用 2、控制线程池的并发数 3、线程池可以对线程进行管理 线程池的示例 1.Client启动类 2.具体…...

导数与微分总复习——“高等数学”
各位CSDN的uu们你们好呀,今天,小雅兰来复习一下之前学过的知识点,也就是导数与微分的总复习,依旧是高等数学的内容,主要是明天就要考高等数学了,哈哈哈,下面,让我们一起进入高等数学…...

Linux软件安装
1.Linux安装JDK 1.安装位置 /opt 2.安装包 jdk-8u171-linux-x64.rpm 3.安装步骤 1.将安装包上传到虚拟机中 [rootlocalhost opt]# ls jdk-8u171-linux-x64.rpm2.执行安装命令 [rootlocalhost opt]# rpm -ivh jdk-8u171-linux-x64.rpm 准备中... #####…...

【表面缺陷检测】基于YOLOX的PCB表面缺陷检测(全网最详细的YOLOX保姆级教程)
写在前面: 首先感谢兄弟们的订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 Hello,大家好,我是augustqi。 今天给大家分享一个表面缺陷检测项目:基于YOLOX的PCB表面缺陷检测(保姆级教程)。多的…...

【C#基础】C# 程序基础语法解析
序号系列文章0【C#基础】初识编程语言C#1【C#基础】C# 程序通用结构总结 文章目录前言基础语法1. using 关键字2. namespace 关键字3. class 关键字4. 成员字段5. 成员方法6. Main 方法7. new 关键字8. 标识符9. 关键字结语前言 😄 大家好,我是writer桑&…...

【webpack】webpack 中的插件安装与使用
一、webpack 插件的作用 通过安装和配置第三方的插件,可以拓展 webpack 的能力,从而让 webpack 用起来更方便。最常用的 的webpack 插件有如下两个: 1.webpack-dev-server(实时打包构建) 类似于 node.js 阶段用到的 no…...

生物素-磺基-活性酯,Sulfo-NHS Biotin科研用试剂简介;CAS:119616-38-5
生物素-磺基-活性酯,Sulfo-NHS Biotin 结构式: 编辑 添加图片注释,不超过 140 字(可选) 英文名称:Sulfo-NHS-Biotin Sulfosuccinimidyl biotin 中文名称:磺酸基-Biotin-N-琥珀酰亚胺基酯 CAS&…...

Debain安装命令
目录 一、安装sudo命令 二、安装jdk8 三、更换软件源 四、Debian 安装 yum 五、安装zip、unzip、curl、lrzsz、NUMA 六、安装Maven 五、问题 一、安装sudo命令 1)执行sudo命令,提示 -bash: sudo: command not found的解决方法 apt-get install s…...

2023-02-10 - 6 聚合
当用户使用搜索引擎完成搜索后,在展示结果中需要进行进一步的筛选,而筛选的维度需要根据当前的搜索结果进行汇总,这就用到了聚合技术。聚合的需求在很多应用程序中都有所体现,例如在京东App中搜索“咸鸭蛋”,然后单击搜…...

Servlet实现表白墙
目录 一、表白墙简介 二、代码实现 1、约定前后端交互的接口 2、后端代码实现 3、前端代码实现 三、效果演示 一、表白墙简介 在表白墙页面中包含三个文本框,分别表示表白者,表白对象,表白内容,在文本框中输入内容之后&…...

[python入门㊸] - python测试函数
目录 ❤ 测试函数 ❤ 单元测试和测试用例 ❤ 可通过的测试 ❤ 不能通过的测试 ❤ 测试未通过时怎么办 ❤ 添加新测试 ❤ 测试函数 学习测试,得有测试的代码。下面是一个简单的函数: name_function.py def get_formatted_name(first, last):…...

通讯录文件操作化
宝子,你不点个赞吗?不评个论吗?不收个藏吗? 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我真的很重…...

为什么 Web3 社交将超越其 Web2 同行
我们最近听到了很多关于 web3 社交媒体平台的消息。但如果你没有跟上,你可能想知道为什么我们已经有了 Twitter、Facebook、Instagram 等,我们还需要 web3 社交。好吧,这一切都取决于谁拥有权力。 在 web2 中,权力掌握在寻求收入最…...

当资深程序员深夜去“打劫”会发生什么?——打家劫舍详解
文章目录一、前言二、概述三、打家劫舍第一晚四、打家劫舍第二晚五、打家劫舍第三晚......一、前言 大家好久不见,正如标题所示,今天我不打算聊一些枯燥的算法理论,我们来聊一聊程序员有多厉害! 注意!!&am…...

linux 线程
文章目录1、线程的概念1.1、进程 vs 线程1.2、线程的种类2、线程的控制2.1、线程的创建2.2、线程的退出2.3、线程的取消2.4、线程的等待2.5、线程的分离2.5、线程清理函数线程清理函数响应的时机线程清理函数不响应的时机3、线程的同步和互斥3.1、锁机制3.1.1、锁的类型3.1.2、…...

Windows 安装appium环境
1 windows Appium环境 1.1 安装Node.js Node.js的安装相对简单,下载安装包安装(安装包node-v19.6.0-x64.msi), nodejs 安装 然后一路狂点下一步就可以了 安装完成后,在终端中输入node -v,显示版本号则表示安装成功 node-v16.13.1 1.2 JDK安装及环境变…...

为什么要在电子产品中使用光耦合器?
介绍 光耦合器不仅可以保护敏感电路,还可以使工程师设计各种硬件应用。光耦合器通过保护元件,可以避免更换元件的大量成本。然而,光耦合器比保险丝更复杂。光耦合器还可以通过光耦合器连接和断开两个电路,从而方便地控制两个电路…...

Vue3 如何实现一个函数式右键菜单(ContextMenus)
前言: 最近在公司 PC 端的项目中使用到了右键出现菜单选项这样的一个工作需求,并且自己现在也在实现一个偶然迸发的 idea( 想用前端实现一个 windows 系统从开机到桌面的 UI),其中也要用到右键弹出菜单这样的一个功能,…...

ffmpeg转码转封装小工具开发
如下图所示,是本人开发的一个转码转封装小工具 其中目标文件视频编码格式支持:H264,H265,VP8,VP9。 目标文件封装格式支持:mp4,mkv,avi,mov,flv。 目标文件音频编码格式支持两个,COPY和AAC&am…...

重入和线程安全
在整个文档中,重入和线程安全用于标记类和函数,从而表明怎样在多线程应用中使用它们。 线程安全函数可以从多个线程同时调用,即使调用使用共享数据也是如此,因为对共享数据的所有引用都是序列化的。也可以从多个线程同时调用重入…...