query_cache_lock 是全局互斥锁而非加速器;mysql 5.7 中 query_cache_type=1 导致所有 select 争抢同一锁,写操作触发全缓存清空,命中率低于5%,锁等待飙升,需彻底删除 my.cnf 中所有 querycache* 配置并重启。

query_cache_lock 是全局互斥点,不是缓存加速器
MySQL 5.7 中 query_cache_type = 1 实际上把每次查询都拖进一个单点竞争路径:所有 SELECT 都要抢同一把 query_cache_lock mutex。写操作(哪怕只是 INSERT INTO audit_log)还会触发全表缓存清空逻辑,导致缓存命中率长期低于 5%,而锁等待却持续飙升。
常见错误现象包括:
-
perf top -p $(pgrep mysqld)频繁出现query_cache_lock符号 -
SHOW STATUS LIKE 'Qcache%'中Qcache_lowmem_prunes远高于Qcache_hits -
Threads_connected持续上涨,但Queries每秒处理量不增反降
SET GLOBAL query_cache_type = OFF 不算真正关闭
运行时执行 SET GLOBAL query_cache_type = OFF 只是临时停用,MySQL 重启后会重新读取配置文件里的残留参数,并自动把 query_cache_type 拉回 1——只要 query_cache_size 被设为非零值,5.7 就认定“你要用”,哪怕你没写 query_cache_type 这行。
必须做三件事:
- 在
my.cnf或mysqld.cnf的[mysqld]段中,删掉或注释掉所有query_cache_*行:query_cache_type、query_cache_size、query_cache_limit、query_cache_min_res_unit - 重启 MySQL(
systemctl restart mysqld),仅reload配置不生效 - 确认
SHOW VARIABLES LIKE 'query_cache%'全部返回OFF或0
5.7.20+ 版本里 query_cache_type 已失效,但变量还在骗人
从 5.7.20 开始,查询缓存被标记为 deprecated;5.7.33+ 和全部 8.0 版本已彻底移除代码路径。但部分 5.7.x 小版本仍保留变量注册逻辑,导致 SHOW VARIABLES LIKE 'query_cache_type' 显示 ON,而 SHOW STATUS LIKE 'Qcache%' 全是 0——这不是配置错了,是缓存入口函数已被绕过。
验证是否真失效:
- 执行
SELECT @@query_cache_type, @@query_cache_size - 再执行两次相同
SELECT * FROM t LIMIT 1 - 查
SHOW STATUS LIKE 'Qcache_hits',若没增长,说明缓存没工作
注意:have_query_cache 恒为 YES,它只表示编译时含旧代码,不能当功能可用依据。
最易被忽略的是残留的 query_cache_size 配置
即使你从没主动配过 QueryCache,只要 my.cnf 里留着 query_cache_size(哪怕值是 1M),5.7 就会启用缓存逻辑并加载锁机制。这个值不为 0,就等于默认打开了全局争抢开关。
禁用后仍要小心残留配置干扰其他缓存指标——比如监控脚本误把 Qcache_free_memory 当作有效指标,其实它早已不反映真实内存使用。











