MariaDB服务器CPU100%占用(应用服务器闲置)及高峰优化求助
MariaDB高峰时段CPU 100%占用优化方案
问题背景
MariaDB 10.6版本在正常时段运行正常,但高峰时段(约25万活跃用户)所有CPU核心持续100%占用,已从8核垂直扩容至32核,问题仍未解决,同时应用服务器资源利用率不足。
系统及数据库关键信息
htop监控结果
All CPU Cores: 100% Mem 5.25G/126G Swp 0K/0K Tasks: 43, 961 thr; 32 running Load average: 150 148 148
系统内核及数据库配置
cat /proc/sys/kernel/threads-max 1030492 cat /proc/sys/kernel/pid_max 4194304 cat /proc/sys/vm/max_map_count 65530
数据库核心配置:
innodb_buffer_pool_size=55G max_connections = 50000
慢查询核心问题
从慢日志来看,两类操作是CPU耗尽的主要原因:
- session_lrp表的UPDATE操作:单条更新耗时超50秒,
Rows_examined高达15万+,说明未通过索引定位目标行,全表扫描直接拉满CPU# Query_time: 50.155999 Lock_time: 0.049785 Rows_sent: 0 Rows_examined: 150617 UPDATE `session_lrp` SET `timestamp` = 1666331640 WHERE `id` = 'pghjejnvf8ou61usog5983h6lihh4jr0'; - GET_LOCK会话锁操作:部分锁等待耗时超15秒,最长达59秒,大量线程因锁阻塞,无效占用CPU资源
# Query_time: 59.245218 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0 SELECT GET_LOCK('62f67a85ee74fca9c3b3c30a20f70f82', 300) AS ci_session_lock;
针对性优化方案
1. 紧急修复session_lrp表索引问题
- 先检查
session_lrp表的id字段索引情况:执行SHOW INDEX FROM session_lrp; - 若
id无主键/唯一索引,立即创建:
注:高峰时段加索引可能锁表,建议先在从库测试,切换流量后执行,或使用MariaDB的Online DDL特性避免锁表。-- 若id是唯一标识,优先设为主键 ALTER TABLE session_lrp ADD PRIMARY KEY(id); -- 若无法设主键,创建普通索引 CREATE INDEX idx_session_id ON session_lrp(id);
2. 重构会话锁机制
- 替换
GET_LOCK为InnoDB行级锁:查询session数据时加FOR UPDATE,利用行锁替代全局锁,减少锁竞争 - 缩短锁等待超时:当前300秒的等待时长过长,建议调整为10秒以内,避免线程长时间空等占用资源
- 迁移会话存储到Redis:将session数据从数据库转移到Redis,利用Redis原子操作实现锁,彻底规避数据库锁竞争问题
3. 调整数据库连接数配置
- 当前
max_connections=50000过大,25万活跃用户不需要这么多连接,建议降低到5000-10000:
过多连接会导致线程上下文切换频繁,额外消耗CPU资源。max_connections = 8000 wait_timeout = 60 interactive_timeout = 60
4. 优化InnoDB核心参数
- 设置
innodb_thread_concurrency为CPU核心数的2倍(32核建议设为64),避免线程过度竞争CPU:innodb_thread_concurrency = 64 - 确保
innodb_adaptive_hash_index处于开启状态(默认开启),加速索引查询 - 若业务允许,调整
innodb_flush_log_at_trx_commit=2,减少磁盘IO对CPU的拖累
5. 系统内核参数优化
- 调整内核参数减少线程切换开销:
echo 1 > /proc/sys/kernel/sched_migration_cost_ns echo 500000 > /proc/sys/kernel/sched_min_granularity_ns - 增大
vm.max_map_count到262144,避免内存映射不足:echo "vm.max_map_count=262144" >> /etc/sysctl.conf sysctl -p
内容的提问来源于stack exchange,提问作者Jayesh
相关产品推荐
相关产品推荐

