have_symlink 是只读状态标识,非配置项;它由 mysql 启动时自动探测系统能力生成,真实控制参数是 skip_symbolic_links=yes(5.6+ 必须使用),且需配合 local_infile=0 和权限管控才能确保安全。

为什么 have_symlink=NO 不是配置项,而是只读状态标识
很多人看到 SHOW VARIABLES LIKE 'have_symlink' 返回 NO 就以为这是个可设参数,其实不是。have_symlink 是 MySQL 启动时自动探测系统能力后生成的只读变量,它反映的是「当前 mysqld 进程是否具备符号链接支持能力」,而非你主动开关的结果。真正控制行为的是 symbolic-links 或 skip_symbolic_links 配置项——改它们才有效。
MySQL 5.6 及以上版本必须用 skip_symbolic_links=yes
在 5.6+ 版本中,symbolic-links=0 已被标记为废弃(deprecated),部分发行版(如 MySQL 8.0.33+)甚至会忽略该设置并静默启用符号链接。官方明确要求使用 skip_symbolic_links=yes 才能确保禁用生效。
- 编辑配置文件
/etc/my.cnf或/etc/mysql/my.cnf,在[mysqld]段落下添加: skip_symbolic_links=yes- 不要同时写
symbolic-links=0,避免配置冲突 - 修改后必须重启服务:
systemctl restart mysqld(或service mysql restart) - 验证是否生效:
mysql -e "SHOW VARIABLES LIKE 'have_symlink';"应返回NO;再执行mysql -e "SELECT @@skip_symbolic_links;"应返回1
禁用后仍显示 have_symlink=YES?检查这三点
即使配置了 skip_symbolic_links=yes,have_symlink 仍可能显示 YES。这不是 bug,而是设计使然——它表示「系统支持符号链接」,但不代表 MySQL 当前允许使用。关键看实际行为是否被阻断:
- 确认
mysqld进程是否真的加载了该配置:运行ps aux | grep mysqld,检查输出中是否含--skip-symbolic-links - 检查错误日志(
log-error指定路径)是否有警告:Warning: Skipping creation of symbolic links - 手动测试是否真被禁用:尝试创建指向
/tmp的表,例如CREATE TABLE t1 (id INT) DATA DIRECTORY='/tmp';,应报错ERROR 1030 (HY000): Got error 168 from storage engine或类似拒绝提示
别漏掉客户端侧的 local_infile 和权限联动风险
单独禁用符号链接只是基础项。攻击者若已拿到数据库账号,仍可能通过 LOAD DATA INFILE + 符号链接绕过限制读取敏感文件——前提是服务端未同步关闭 local_infile。
- 务必在
[mysqld]中加:local_infile=0 - 同时在客户端连接时禁用该功能:
mysql --local-infile=0 -u user -p - 检查用户权限:
SELECT user, host, File_priv FROM mysql.user WHERE File_priv = 'Y';,非必要用户应收回FILE权限 - 注意:即使
have_symlink=NO,只要local_infile=1且用户有FILE权限,仍可能被用于本地文件读取攻击
SHOW VARIABLES 的输出。











