mysql 8.0 中 query_cache_type 和 query_cache_size 已被硬编码移除,配置即报错且服务无法启动,必须彻底删除 my.cnf 中所有相关参数。

MySQL 8.0 启动报 Unknown variable 'query_cache_type' 怎么办
直接删掉配置文件里的 query_cache_type 和 query_cache_size。这两个参数在 MySQL 8.0 中已被硬编码移除,不是“不生效”,而是解析器根本认不出——启动时会报错并拒绝加载。Percona Server 8.x、MariaDB 10.6+ 同样如此。别试图加 skip-query-cache 或注释掉,只要配置项存在且未被完全删除,就可能触发失败。
为什么一张表 UPDATE 就让全库相关缓存失效
查询缓存的失效逻辑是表粒度的,不是语句粒度或结果粒度。只要任意连接对表 t_user 执行了 INSERT/UPDATE/DELETE,所有命中过 t_user 的缓存条目(哪怕只是 SELECT count(*) FROM t_user WHERE id = 1)都会被立即标记为无效。这不是延迟清理,而是同步广播式失效,期间还持有全局锁。写多读少的业务里,缓存命中率常低于 1%,但锁开销却始终在线。
SELECT SQL_CACHE 在 MySQL 5.7.20+ 还能用吗
不能。从 MySQL 5.7.20 开始,SQL_CACHE 和 SQL_NO_CACHE 提示已被忽略,语法虽不报错,但实际不触发任何缓存行为。如果你在 5.7.20–5.7.39 之间看到缓存统计变量(如 Qcache_hits)非零,那大概率是之前版本残留的缓存未被清空,而非新查询命中了缓存。真正可控的缓存行为只存在于 5.7.19 及更早版本,且必须同时满足:query_cache_type = 1、query_cache_size > 1048576、查询不含 NOW() 等不确定性函数。
替代方案里最容易被低估的一点
应用层缓存(比如 Redis)不是“比查询缓存更好”,而是彻底绕开了它的设计缺陷:它不共享、不全局锁、不失效风暴、可按业务语义控制 TTL 和刷新时机。但很多人只做了一半——把 SELECT * FROM config WHERE type='pay' 缓存起来,却没同步监听该表的变更事件。结果还是脏数据。真要替代,得配好 binlog 解析或业务层双写,否则只是把问题从数据库搬到了缓存层。











