各位数据库同行,今天给大家分享一个刚踩的热乎坑:我们一台跑CentOS的MySQL核心库,大清早突然收到监控告警------CPU使用率飙到800%+,内存占用也直奔90%,业务接口开始频繁超时。
登录服务器敲下top,输出直接给我整懵了:

一眼就看到了异常:
-
PID为117647的mysqld进程,CPU:113.0%,MEM:66.21%,确实压力山大
-
但更扎眼的是下面这个进程:PID为5869的进程,这个进程的用户是setroubleshoot+,CPU:82.6%,MEM:17.27%,VIRT更是夸张到7725316(约7.3G)
这个setroubleshootd是什么?查了下才知道,它是SELinux的故障诊断进程,专门用来收集和分析SELinux的拒绝访问日志。
一、根因分析:为什么setroubleshootd会吃这么多资源?
先确认了SELinux状态:getenforce返回Enforcing,安全策略是开启的。

问题根源其实很清晰:
-
大量SELinux告警爆发:MySQL的某些操作(比如数据文件访问、端口监听、线程创建)触发了SELinux规则,产生了大量AVC拒绝日志
-
日志堆积+分析过载:setroubleshootd需要实时解析这些日志,生成告警信息。当告警量短时间内爆发时,进程就会疯狂占用CPU和内存,甚至比业务进程还能吃资源
-
恶性循环:setroubleshootd抢占资源→MySQL性能进一步下降→业务报错更多→触发更多SELinux告警→资源占用再创新高
简单来说不是SELinux本身有问题,而是没配置好的SELinux,通过setroubleshootd这个进程,把自己变成了性能杀手。
二、影响评估
这次问题带来的影响比想象中更广,不只是MySQL,整个服务器都在抗压,主要影响如下:
-
业务层面:MySQL查询响应时间从几十毫秒涨到几秒,部分读写请求超时,用户反馈页面加载慢
-
系统层面:内存和CPU被大量占用,服务器负载飙升,差点触发OOM导致其他进程被杀死
-
安全层面:虽然SELinux在工作,但setroubleshootd本身的高负载会让运维人员淹没在海量告警里,反而忽略了真正需要关注的安全风险
三、解决方案:从临时止血到根治
方案1:临时紧急止血(适合业务高峰期)
先把资源抢回来,让MySQL恢复正常:
css
# 停止setroubleshoot相关服务systemctl stop setroubleshootdsystemctl stop setroubleshoot
或者如果服务停不掉时可以直接杀进程
apache
kill -9 5869
执行后观察top,MySQL的CPU和内存占用会快速回落,业务响应恢复。
⚠️ 注意:这只是临时方案,重启服务器后进程会再次启动,治标不治本。
方案2:永久解决(推荐,从根源消除告警)
定位告警根源,先找到到底是哪些MySQL操作触发了SELinux:
bash
# 查看最近的MySQL相关AVC拒绝日志grep mysql /var/log/audit/audit.log | tail -20

- 生成并应用SELinux策略
用audit2allow工具分析日志,自动生成允许规则:
nginx
# 分析日志,生成规则模块audit2allow -a -M mysql_local# 安装模块到系统semodule -i mysql_local.pp
- 验证并重启服务
再次查看日志,确认MySQL相关的AVC拒绝已经消失,然后重启服务:
sql
systemctl start setroubleshootdsystemctl start setroubleshoot
此时setroubleshootd进程会恢复正常,资源占用大幅下降。
方案3:临时关闭SELinux
如果暂时没时间梳理规则,可以先切到Permissive模式,如果生成环境安全要求没那么高,则可以关闭。如果有安全要求,则处理后再开启:
apache
setenforce 0

⚠️警告:这会关闭SELinux的强制访问控制,仅建议作为过渡方案,生产环境不推荐长期使用。
任何SELinux规则变更,都要先在测试环境验证,避免影响业务。
四、经验总结:给DBA的几点提醒
SELinux不是洪水猛兽,它能有效防止提权和恶意代码执行,但需要正确配置,否则会变成性能杀手。另外,需重视日志分析,setroubleshootd的高负载本质是大量告警未处理的表现,及时分析并解决底层问题才是根本。因此平时我们不仅要监控MySQL,还要监控系统级进程和SELinux状态,提前发现异常。
这次排查让我深刻体会到:系统安全和性能从来不是对立的,关键在于精细化运维。别让一个小小的SELinux配置问题,拖垮了你精心优化的MySQL集群。