mysql 8.0 彻底删除 query cache 模块,非禁用而是源码级移除,配置即报错、服务无法启动;因其全局锁导致高并发排队、表级失效致命中率长期低于5%、字节级匹配与现代orm/预处理不兼容,且开销反超收益,故被移除以释放资源给 innodb 缓冲池和应用层缓存。

MySQL 8.0 不是“关掉了查询缓存”,而是从源码里彻底删掉了 query_cache_type、query_cache_size 等所有相关逻辑——配置即报错,服务根本起不来。它对性能的影响不是“少了个加速器”,而是移除了一个长期卡住并发的全局瓶颈。
my.cnf 里写 query_cache_type = 0 就启动失败
这不是配错了,是变量名本身已被编译器剔除。MySQL 8.0.3 起,整个 Query Cache 模块物理消失,mysqld 解析配置时直接报 Unknown system variable 'query_cache_type' 并退出。Percona Server 8.x、MariaDB 10.6+、RDS 参数组、Docker 镜像全都不兼容。
- 必须手动删掉
my.cnf(或my.ini)中所有以query_cache_开头的行,一个都不能留 - 别试图设成
0或OFF—— 它已经不是开关,是“没这个东西” - 升级前没清理?日志末尾一定卡在这句报错,服务压根不会进入初始化阶段
Waiting for query cache lock 是 MySQL 5.7 的典型卡顿信号
这个状态在 8.0 里彻底消失,因为底层的全局锁 LOCK_query_cache 被一并删除了。在 5.7 中,它会导致:
- 哪怕只是检查
SELECT * FROM users WHERE id = 123是否命中缓存,也得排队等这把锁 - 一次
UPDATE users SET name='x' WHERE id=123,不仅要清空整张users表所有缓存,清空过程本身还要持锁 -
SHOW PROCESSLIST里大量线程显示该状态,%systemCPU 异常升高,实际执行 SQL 的时间反而变少
缓存命中率长期低于 5% 却还在吃资源
Query Cache 的字节级匹配机制和现代应用完全脱节:
-
SELECT id FROM t WHERE x=1和SELECT id FROM t WHERE x = 1(空格差一位)就是两个 key - ORM(MyBatis/Django/Sequelize)生成的语句带随机空格、注释、参数占位符,基本不命中
-
PREPARE/EXECUTE预处理语句、含NOW()、RAND()、用户变量、子查询的语句,直接绕过缓存路径 - 分区表默认禁用查询缓存,而生产环境大表基本都分区——意味着你白配了
更关键的是:即使 query_cache_size = 0,缓存判断逻辑仍存在,CPU 开销照常发生,实测升高 13%~18%。
真正被释放的资源去了哪
删掉 Query Cache 不是放弃缓存,而是把内存、CPU、锁调度逻辑让给更可控的机制:
-
innodb_buffer_pool_size成为唯一核心缓存开关:它缓存的是数据页,支持 MVCC、LRU-K 淘汰、无全局锁 - 应用层缓存(Redis/Memcached)由业务控制生命周期:可按 key 粒度失效、支持 TTL、能穿透更新
- 代理层(如 ProxySQL)支持基于规则的 SQL 哈希缓存,兼容预处理语句,且不干扰 MySQL 内核
最容易被忽略的一点是:Query Cache 的“失效”不是偶尔发生,而是每次写操作都强制触发表级清空——它在高并发写场景下,不是缓存,是刹车片。











