正确答案是:have_symlink=NO不是可配置项,仅是只读状态标识;真正控制符号链接启用与否的是skip_symbolic_links=yes(5.6+必需),且须配合local_infile=0和FILE权限回收才能确保安全。

have_symlink 显示 YES 并不等于符号链接功能“已开启可用”——它只是告诉你操作系统支持该能力;真正决定 MySQL 是否允许使用符号链接的,是配置项 skip_symbolic_links,且默认行为因版本而异。
MySQL 5.6+ 默认禁用符号链接,但不是靠 have_symlink 控制
have_symlink 是只读状态标识,不是开关。你看到 SHOW VARIABLES LIKE 'have_symlink' 返回 YES,只说明系统有能力支持符号链接(比如 Linux 下内核和文件系统支持),不代表 MySQL 允许你用。
- MySQL 5.6 起,
symbolic-links=0已被标记为 deprecated,官方要求改用skip_symbolic_links=yes - MySQL 8.0.33+ 会直接忽略
symbolic-links=0,并静默启用符号链接——写这个等于白写 - 新版本编译默认已是
skip_symbolic_links=ON(即禁用),所以多数安装后实际就是禁用状态
想开启符号链接?先确认是否真有必要
开启符号链接意味着允许 CREATE TABLE ... DATA DIRECTORY 或 INDEX DIRECTORY 指向任意路径,包括 /tmp、/proc 等敏感位置。攻击者可借此绕过权限限制读写文件。
- 除非业务强依赖跨目录表空间管理(如分离冷热数据),否则不建议开启
- Windows 上默认启用
.sym文件支持,但 Linux 生产环境普遍主动禁用 - 开启前必须同步评估:
local_infile是否为ON?用户是否有FILE权限?SELinux/AppArmor 是否放行?
如果真要开启:只改 skip_symbolic_links=no 不够
MySQL 不提供 “开启符号链接” 的显式配置项,只有禁用开关。所谓“开启”,本质是取消禁用——但必须确保没有其他机制拦截。
- 在
[mysqld]段下删除或注释掉skip_symbolic_links=yes - 不要写
skip_symbolic_links=no—— 官方文档未定义该值,部分版本可能解析失败 - 确认
local_infile=1(否则LOAD DATA INFILE仍受限) - 重启服务后执行
SELECT @@skip_symbolic_links;,返回0才表示禁用已取消 - 实测建表:
CREATE TABLE t1 (id INT) DATA DIRECTORY='/tmp/test';—— 成功创建才代表真正生效
验证时别只看 have_symlink,重点看报错和行为
即使 have_symlink=YES 且 @@skip_symbolic_links=0,仍可能因路径权限、SELinux、AppArmor 或挂载选项(如 noexec、nosuid)导致符号链接操作失败。
- 错误
ERROR 1030 (HY000): Got error 168 from storage engine通常表示符号链接被底层拒绝,而非 MySQL 配置问题 -
DATA DIRECTORY路径必须是绝对路径、目录存在、MySQL 进程用户(如mysql)有读写权限 - 容器环境(如 Docker)中,宿主机挂载路径若未启用
follow_symlinks,也会静默失败


















