关于xxl-job中的慢sql引发的磁盘I/O飙升导致拖垮整个数据库服务

本文涉及的产品
RDS AI 助手,专业版
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 关于xxl-job中的慢sql引发的磁盘I/O飙升导致拖垮整个数据库服务

背景:

某天突然发现服务探测接口疯狂告警、同时数据库CPU消耗也告警,最后系统都无法访问;

查看服务端日志,发现大量的报错如下:

CommunicationsException: Communications link failure :The last packet successfully received from the server was 201,106 milliseconds ago. The last packet sent successfully to the server was 200,106 milliseconds ago.

起先以为服务出现问题,服务重启后现象依旧。

调查:

通过iostat命令观察到cpu的iowait非常高,再加上服务端的日志报错也是和数据库相关的,然后就把怀疑的方向转移到Mysql是否存在慢SQL拖垮了整个服务。

最后查到是我们使用的xxl-job中间件的一个慢SQL阻塞了整个系统的资源

SELECT t.id
FROM xxl_job_log AS t
WHERE t.trigger_code = 200
AND t.handle_code = 0
AND t.trigger_time <= '2023-02-1 23:36:51.57'
AND t.executor_address NOT IN (
SELECT t2.registry_value
FROM xxl_job_registry AS t2
)

查询使用命令如下

1.查看哪些表被锁:show OPEN TABLES where In_use > 0;
2.查询正在执行的SQL,发现大量SQL执行阻塞了几百秒:
select * from information_schema.processlist where db=‘ db_xxx ‘ and info is not null;
3.直接取出索引的进程ID,拼装成kill语句,取出来执行,干掉阻塞中的索引进程:
select concat(‘kill ‘, id,‘;‘) from information_schema.processlist where db=‘db_xxx ‘ and info is not null;

经过在网上的查询也可以发现官方提出了类似的问题

https://gitee.com/xuxueli0323/xxl-job/issues/I57M1Y

https://github.com/xuxueli/xxl-job/issues/596

为什么数据库的慢SQL会导致CPU的IO WAIT升高呢

我们先看一下计算机是怎么管理磁盘IO操作的。计算机发展早期,磁盘和内存的数据传输是由CPU控制的,也就是说从磁盘读取数据到内存中,是需要CPU存储和转发的,期间CPU一直会被占用。我们知道磁盘的读写速度远远比不上CPU的运转速度。这样在传输数据时就会占用大量CPU资源,造成CPU资源严重浪费。

后来有人设计了一个IO控制器,专门控制磁盘IO。当发生磁盘和内存间的数据传输前,CPU会给IO控制器发送指令,让IO控制器负责数据传输操作,数据传输完IO控制器再通知CPU。因此,从磁盘读取数据到内存的过程就不再需要CPU参与了,CPU可以空出来处理其他事情,大大提高了CPU利用率。这个IO控制器就是“DMA”,即直接内存访问,Direct Memory Access。现在的计算机基本都采用这种DMA模式进行数据传输。

通过上面内容我们了解到,IO数据传输时,是不占用CPU的。当应用进程或线程发生IO等待时,CPU会及时释放相应的时间片资源并把时间片分配给其他进程或线程使用,从而使CPU资源得到充分利用。所以,假如CPU大部分消耗在IO等待(wa)上时,即便CPU空闲率(id)是0%,也并不意味着CPU资源完全耗尽了,如果有新的任务来了,CPU仍然有精力执行任务。如下图:

在DMA模式下执行IO操作是不占用CPU的,所以CPU IO等待(上图的wa)实际上属于CPU空闲率的一部分。所以我们执行top命令时,除了要关注CPU空闲率,CPU使用率(us,sy),还要关注IO Wait(wa)。注意,wa只代表磁盘IO Wait,不包括网络IO Wait。

 

因为CPU处理数据的速度远远大于IO准备数据的速度。所以再进行“读操作”时,DMA负责将数据从磁盘拷贝到内核空间,注意是拷贝不是移动,然后cpu再从内核空间拷贝到用户空间。所以,cpu等待io就绪,在“读操作”时,等的就是DMA将数据从磁盘拷贝到内核空间。

理论与实际结合

那么反应到我们遇到的这个场景就是:iowait是cpu处于空闲状态,因为服务端要做事情之前一般要查一下库如用户权限之类会查用户权限表,现在mysql那里索引出问题了,io资源全被阻塞住了,达到了磁盘IO的瓶颈,服务端这边又一直等待数据从磁盘拷贝到dma(那个问题SQL对应的表数据达到千万级别),磁盘的传输效率又很低所以要把所有的查询返回结果拷贝完非常的耗时,所以才会出现上面的SQL执行了几百秒还没有结束,而系统代码只有再获取到数据库的查询结果后,才能走下面的计算逻辑,那可不是cpu空闲着也没啥可做的,就只是傻乎乎地在等着io拷贝结束嘛,而那些问题SQL又一直占据着IO资源迟迟不释放,就导致了整个系统的不可用。

当把这些问题SQL kill掉之后,系统恢复正常,后面我们针对这个场景增加了一个定时任务来清理那些没用的记录。

后续如何避免MYSQL使用中的慢SQL导致CPU-IOWAIT偏高致使整个系统不可用

问题源头

CPU的消耗主要在 用户、系统、IO等待、软硬中断、空闲。

主要针对用户、IO等待进行优化(其他方面较难改变)

用户:  用户这块主要是用户空间CPU消耗,各种逻辑运算; 比如:正在进行大量tps

以及函数/排序/类型转化/逻辑IO访问…

IO等待:等待IO请求的完成

主要是这两者消耗了大部分的CPU,导致吞吐量下降、查询响应时间增加、慢查询增加。

减少CPU消耗

1.  减少等待

减少IO量:创建适合的索引,空间换时间,提示慢SQL的执行速度。

提升IO处理能力:加大cache、加大磁盘/SSD

2. 减少计算

1)  减少逻辑运算:

避免使用函数,将运算转移至易扩展的应用服务器中

如substr等字符运算,dateadd/datesub等日期运算,abs等数学函数

减少排序,利用索引取得有序数据或避免不必要排序

如union all代替 union,order by 索引字段等

禁止类型转换,使用合适类型并保证传入参数类型与数据库字段类型绝对一致

如数字用tiny/int/bigint等,必需转换的在传入数据库之前在应用中转好

简单类型,尽量避免复杂类型,降低由于复杂类型带来的附加运算。更小的数据类型占用更少的磁盘、内存、cpu缓存和cpu周期

2) 减少逻辑IO量:

index,优化索引,减少不必要的表扫描

如增加索引,调整组合索引字段顺序,去除选择性很差的索引字段等等

table,合理拆分,适度冗余

如将很少使用的大字段拆分到独立表,非常频繁的小字段冗余到“引用表”

SQL,调整SQL写法,充分利用现有索引,避免不必要的扫描,排序及其他操作

如减少复杂join,减少order by,尽量union all,避免子查询等

数据类型,够用就好,减少不必要使用大字段

如tinyint够用就别总是int,int够用也别老bigint,date够用也别总是timestamp

减少query请求量

适当缓存,降低缓存数据粒度,对静态并被频繁请求的数据进行适当的缓存

如用户信息,商品信息等

优化实现,尽量去除不必要的重复请求

如禁止同一页面多次重复请求相同数据的问题,通过跨页面参数传递减少访问等

合理需求,评估需求产出比,对产出比极端底下的需求合理去除

3. 升级cpu

若经过减少计算和减少等待后还不能满足需求,cpu利用率还高,使用杀手锏升级cpu(使用更快更多的CPU)

 

相关文章:

关于job-admin 拖垮数据库

xxl job 运行性能问题

The last packet successfully received from the server was xx milliseconds ago

I/O多路复用

MySQL优化5之CPU消耗过高

io等待为什么引发cpu过高

一次I/O问题引发的P0重大故障

 

本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。

相关实践学习
自建数据库迁移到云数据库
本场景将引导您将网站的自建数据库平滑迁移至云数据库RDS。通过使用RDS,您可以获得稳定、可靠和安全的企业级数据库服务,可以更加专注于发展核心业务,无需过多担心数据库的管理和维护。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
相关文章
|
9月前
|
SQL 机器学习/深度学习 人工智能
从“写SQL”到“聊数据”:NL2SQL如何用自然语言解锁数据库?
本文系统性地阐述了自然语言转SQL(NL2SQL) 技术如何让非技术背景的业务分析师实现数据自助查询,从而提升数据驱动决策的效率与准确性。
从“写SQL”到“聊数据”:NL2SQL如何用自然语言解锁数据库?
|
10月前
|
存储 关系型数据库 数据库
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
本文通过一个 Agentic RAG 应用的完整构建流程,展示了如何借助 RDS Supabase 快速搭建具备知识处理与智能决策能力的 AI 应用,展示从数据准备到应用部署的全流程,相较于传统开发模式效率大幅提升。
附部署代码|云数据库RDS 全托管 Supabase服务:小白轻松搞定开发AI应用
|
8月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1424 152
|
8月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1034 156
|
11月前
|
SQL 关系型数据库 MySQL
Go语言数据库编程:使用 `database/sql` 与 MySQL/PostgreSQL
Go语言通过`database/sql`标准库提供统一数据库操作接口,支持MySQL、PostgreSQL等多种数据库。本文介绍了驱动安装、连接数据库、基本增删改查操作、预处理语句、事务处理及错误管理等内容,涵盖实际开发中常用的技巧与注意事项,适合快速掌握Go语言数据库编程基础。
1385 213
|
8月前
|
SQL 人工智能 Linux
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
709 5
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
|
7月前
|
SQL 存储 监控
SQL日志优化策略:提升数据库日志记录效率
通过以上方法结合起来运行调整方案, 可以显著地提升SQL环境下面向各种搜索引擎服务平台所需要满足标准条件下之数据库登记作业流程综合表现; 同时还能确保系统稳健运行并满越用户体验预期目标.
399 6
|
8月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
8月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
583 8

热门文章

最新文章