MariaDB禁用查询缓存仍CPU占满100%,请求技术排查
MariaDB CPU占满及Query Cache相关问题分析与解决
核心问题拆解与解答
1. 为何query_cache_size会被自动修改?
有两种常见可能性:
- 权限用户手动修改:拥有
SUPER权限的用户(如root)可通过SET GLOBAL query_cache_size = 16777216;语句修改全局参数,需排查操作日志确认是否有此类操作。 - 第三方工具/面板自动调整:作为虚拟主机服务商,若使用cPanel、Plesk等管理面板,部分面板的自动优化逻辑可能会根据负载自动调整query cache参数,需检查面板的数据库优化设置。
可通过查看MariaDB错误日志(通常路径为/var/log/mariadb/mariadb.log或/var/log/mysql/error.log),搜索query_cache_size或SET GLOBAL关键字,定位参数修改的时间和来源。
2. 长时间运行的DROP DATABASE进程是关键线索吗?
是的,这个进程是导致CPU占满和query cache锁等待的核心原因:
DROP DATABASE操作需要遍历并关闭目标库下的所有表文件,当库内表数量多、表文件大或磁盘IO性能不足时,该操作会卡在closing tables状态。- 此时query cache需要获取全局锁来维护缓存一致性(即便
query_cache_type=0,只要query_cache_size>0,锁逻辑仍会触发),大量请求会进入Waiting for query cache lock状态,最终导致CPU被占满。
3. 为何have_query_cache始终显示YES?
这个参数仅表示MariaDB编译时是否包含query cache模块,而非当前是否启用缓存。只要编译时未移除该模块,无论是否设置query_cache_size=0,have_query_cache都会显示YES,属于正常现象,无需担忧——只要query_cache_size=0且query_cache_type=0,query cache就是完全禁用状态。
解决步骤
处理卡住的
DROP DATABASE进程- 执行
KILL 6301;(替换为对应进程ID)终止该操作,若进程无法正常终止,可尝试KILL CONNECTION 6301;。 - 操作完成后,手动检查磁盘上的数据库目录(通常在
/var/lib/mysql/下),若目标库目录仍存在,可手动删除。
- 执行
阻止
query_cache_size被恶意/自动修改- 在
my.cnf/my.ini中添加额外配置,强化禁用:query_cache_size = 0 query_cache_type = 0 query_cache_limit = 0 - 限制
SUPER权限的用户范围,仅授权给可信管理员。 - 关闭虚拟主机面板中自动调整数据库参数的功能。
- 可通过事件调度器定期检查参数,若发现
query_cache_size不为0则自动修正:CREATE EVENT IF NOT EXISTS check_query_cache ON SCHEDULE EVERY 1 MINUTE DO SET GLOBAL query_cache_size = 0;
- 在
优化虚拟主机数据库运维
- 开启慢查询日志,监控
DROP DATABASE、ALTER TABLE等耗时操作,及时介入处理。 - 对用户的数据库操作权限进行细分,避免普通用户执行高风险的大规模操作。
- 开启慢查询日志,监控
内容的提问来源于stack exchange,提问作者Vikas Singhal
相关产品推荐
相关产品推荐

