真正防旁路攻击必须设query_cache_size=0,因其彻底释放内存并禁用缓存逻辑;仅设query_cache_type=off在size>0时仍可能触发初始化,且mysql 5.7及以下默认启用,8.0+已移除,需通过show variables like 'query_cache%'和show status like 'qcache%'双重验证运行时值全为0。

phpMyAdmin 本身不控制 MySQL 的查询缓存,关闭它必须改 MySQL 配置;仅在 phpMyAdmin 界面里禁用“历史”或“书签”完全无效,因为查询缓存是服务端全局机制,与 Web 界面无关。
为什么关掉 MySQL 的 query_cache_size 才算真正防旁路泄露
攻击者可通过反复执行相同 SELECT 语句并测量响应时间差异,判断某条记录是否存在(例如 SELECT 1 FROM users WHERE email='a@b.com'),这就是基于查询缓存的时序旁路攻击。只要 query_cache_type 是 ON 且 query_cache_size > 0,该通道就存在——哪怕你从不点「历史」、不存书签、不导出数据。
- MySQL 5.7 及更早版本默认启用查询缓存,8.0+ 已彻底移除,所以首先要确认你的 MySQL 版本
-
query_cache_size = 0比query_cache_type = OFF更可靠:前者直接释放内存、禁用所有缓存逻辑;后者在 size > 0 时仍可能触发部分初始化行为 - phpMyAdmin 的 SQL 执行界面不会显示缓存状态,也不能开关它——你看到的“执行时间”包含网络、PHP、MySQL 多层耗时,不能用于判断缓存是否命中
如何验证 query_cache_size 确实已关闭
别只看配置文件写了什么,得进 MySQL 实例查运行时值:
- 登录 MySQL 后执行:
SHOW VARIABLES LIKE 'query_cache%';—— 确认query_cache_size显示为0,且query_cache_type是OFF - 再执行:
SHOW STATUS LIKE 'Qcache%';—— 所有值应全为0(如Qcache_hits、Qcache_inserts);若仍有非零值,说明配置未生效或被动态 SET 过 - 检查 my.cnf 是否被多处加载:MySQL 可能读取 /etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf 等多个路径,
mysqld --verbose --help | grep "Default options"可确认顺序
容易被忽略的兼容性陷阱
某些旧版 PHP 扩展(如 mysql_*,虽已废弃)或自定义监控脚本会主动调用 mysql_query("SELECT @@query_cache_size"),若返回非零值,可能误判环境安全。更麻烦的是:
- Docker 或云数据库 RDS 环境中,
my.cnf可能被容器启动参数或控制台配置覆盖,手动改文件无效 - 使用 systemd 启动 MySQL 时,若
EnvironmentFile指向了另一个配置,优先级可能高于 /etc/my.cnf - phpMyAdmin 的
$cfg['Servers'][$i]['extension'] = 'mysqli'设置不影响缓存,但若误配成mysql(PHP 7.0+ 不支持),会导致连接失败,掩盖真实缓存状态
最常出问题的地方是:运维以为升级了 phpMyAdmin 就安全了,却没碰 MySQL 配置;或者只在测试库关了缓存,生产库仍开着——而旁路攻击只需要一次可测的查询入口。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











