mysql 8.0.3起彻底移除query cache模块,相关变量(如query_cache_type)被源码删除,配置即报错;须清理my.cnf中所有query_cache_*项,否则无法启动。

MySQL 8.0 启动就报 Unknown variable 'query_cache_type'
这不是配置写错了,是 MySQL 8.0.3 起直接删掉了整个 Query Cache 模块。所有相关变量——query_cache_type、query_cache_size、query_cache_limit——全被从源码中移除,连配置解析器都不认识它们。哪怕只在 my.cnf 里写一行 query_cache_type = 0,mysqld 启动时就会拒绝加载并报错退出。
为什么不是“默认关闭”,而是“物理删除”
Query Cache 的问题不是开关能解决的,它的设计缺陷已深嵌执行路径:
-
LOCK_query_cache是全局互斥锁,每次 SELECT 都要抢它,多核机器上反而卡死并发 - 缓存键基于 SQL 字符串字节级比对:
SELECT * FROM t WHERE id=1和SELECT * FROM t WHERE id = 1就是两个 key - 一张表执行一次
UPDATE,所有关联该表的缓存条目全部清空,且清空过程也持锁 - 预处理语句(
PREPARE/EXECUTE)、含用户变量(@x)、子查询嵌套较深的查询,一律绕过缓存 - 命中率长期低于 5%,但每次 SELECT 仍要走一遍缓存判断逻辑,纯属开销税
升级后必须清理配置文件中的所有 query_cache_* 行
如果你是从 MySQL 5.7 升级上来的,my.cnf 或 my.ini 中残留的 query_cache_* 配置必须手动删干净:
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
- Percona Server 8.x、MariaDB 10.6+ 同样不识别这些配置,别指望兼容
- Docker 容器或云数据库(如 RDS)若使用自定义参数组,也要检查并删除残留项
- 哪怕只留一个
query_cache_size = 0,也会导致服务无法启动 - 验证是否清理干净:启动后执行
SHOW VARIABLES LIKE 'query_cache%';,应返回空结果集
替代方案不是“换个缓存”,而是换层级、换控制权
Query Cache 失败的本质,是在 SQL 解析层强行做结果级缓存,却扛不住数据一致性压力。真正有效的方向是分层剥离:
- 应用层缓存:对确定性高、更新不频繁的结果(如配置表、省市区列表),用 Redis 缓存序列化后的结果,自己控制 key、TTL 和失效逻辑
- 代理层缓存:如 ProxySQL 支持通配匹配(
SELECT * FROM users WHERE id = ?),可设 TTL,比原生 Query Cache 实用得多 - InnoDB Buffer Pool:把
innodb_buffer_pool_size设对,它缓的是数据页,无锁、无整表失效风暴,命中后直接内存读
最常被忽略的一点是:即使你没显式配置任何 query_cache_*,只要配置文件里还留着旧参数,MySQL 8.0 就不会给你启动的机会——它不警告、不兼容、不降级,只拒绝。










