MySQL 8.0.3+ 彻底删除查询缓存,query_cache_type等参数物理不存在,配置即启动失败;必须清除my.cnf中所有含query_cache_的行(含注释),并升级JDBC驱动至8.0.33+。

MySQL 8.0 里根本不能设置查询缓存参数——不是配不对,是代码里真没了。 你看到的 query_cache_type、query_cache_size 等配置项,在 MySQL 8.0.3 及之后版本中已被物理删除,连变量定义都从源码里抹掉了。任何残留配置都会导致 mysqld 启动失败,报错 Unknown system variable 'query_cache_type'。
my.cnf 里还留着 query_cache_ 配置,会怎样?
直接启动失败,不是警告,是退出。哪怕这行被注释了,只要存在以 query_cache_ 开头的文本(包括 # query_cache_size = 0),mysqld 解析时就会报错。
- 必须手动删掉
my.cnf(或my.ini)中所有含query_cache_的行,注释行也得清干净 - Docker 镜像、RDS 参数组、Percona Server 8.x 同样不识别——不存在“设为 OFF 就能绕过”的兼容模式
- 如果你用的是 Kubernetes ConfigMap 或 Helm chart,检查模板是否硬编码了这些参数
连接时 JDBC 报 query_cache_size 错误,其实是驱动没换
旧版 JDBC 驱动(如 com.mysql.jdbc.Driver)在握手阶段会主动探测 query_cache_size,而 8.0 不响应这个变量,结果就抛出 Unknown system variable。这不是数据库配错了,是客户端在问一个已不存在的东西。
- 驱动类名必须换成
com.mysql.cj.jdbc.Driver - Maven 依赖要确认实际加载的是
mysql-connector-java-8.0.33+,不是残留的 5.x 版本 - Spring Boot 项目需检查是否显式排除了
spring-boot-starter-jdbc,导致降级使用旧驱动 - 连接 URL 必须补全
?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false等 8.0 强制参数,否则握手失败日志可能被误判为缓存变量问题
为什么 MySQL 8.0 彻底删掉查询缓存?
不是“优化不好”,而是它的底层机制和现代 OLTP 场景天然冲突。核心问题是:全局锁 + 表级失效 + 字节级匹配,三者叠加后,在真实业务中几乎无法稳定收益。
- 每次
UPDATE users SET name='x' WHERE id=123,都要持LOCK_query_cache扫描整个哈希表,标记/删除所有关联该表的缓存条目 - 哪怕只是执行
SELECT * FROM users WHERE id = 123查缓存,也得排队等这个锁,高并发下大量线程堆在锁上,%system CPU异常升高 - 缓存只认字面量:
SELECT * FROM t WHERE id = 1和SELECT * FROM t WHERE id=1(少个空格)就是两条不同缓存;预处理语句(WHERE id = ?)完全不进缓存 - 真正该调优的是
innodb_buffer_pool_size:它缓存数据页,支持 MVCC、LRU-K 淘汰、无全局锁,且直接受益于索引和事务设计
最易被忽略的一点:升级后性能下降,往往不是因为“缓存没了”,而是 persisted_variables 覆盖了你的 my.cnf,或者统计信息没刷新导致优化器选错执行计划——这些比找“替代查询缓存”更紧迫。


















