无法绕过 secure_file_priv,只能适配:查值用 show variables like 'secure_file_priv',结果为 null(全禁)、路径(仅限该目录)或空字符串(新版已移除);修改需编辑配置文件、创建目录、赋权 mysql:mysql、重启服务,且路径必须绝对。

直接结论:你无法绕过 secure_file_priv,只能适配它——要么把文件放到它指定的目录,要么改配置并重启 MySQL 服务。
查当前 secure_file_priv 值是第一步
连上 MySQL 后立刻执行:SHOW VARIABLES LIKE 'secure_file_priv';
结果只有三种可能:
-
NULL:所有SELECT ... INTO OUTFILE、LOAD DATA INFILE、LOAD_FILE()全部被硬性拒绝,连FILE权限也没用 -
/var/lib/mysql-files/(或其他具体路径):只允许读写该路径下的文件,子目录也得显式存在且有权限 - 空字符串
'':旧版允许,但 MySQL 8.0.28+ 已移除支持,设了会启动失败
改配置必须重启,且目录权限不能漏
修改 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf 的 [mysqld] 段:
- 加一行:
secure_file_priv = /your/export/dir(路径必须绝对、已存在) - 创建目录:
sudo mkdir -p /your/export/dir - 赋权:
sudo chown mysql:mysql /your/export/dir(注意不是root,也不是777) - 重启:
sudo systemctl restart mysql(Docker 用户需重新构建或挂载目录)
改完不重启=没改;目录存在但属主不是 mysql = 执行时仍报 ERROR 1 (HY000)。
LOAD DATA INFILE 和 SELECT ... INTO OUTFILE 路径必须是绝对路径
即使 secure_file_priv 设为 /tmp/,也不能写成 INTO OUTFILE 'user.txt'(相对路径会被拒):
- ✅ 正确:
SELECT * INTO OUTFILE '/tmp/user.txt' FROM user; - ❌ 错误:
SELECT * INTO OUTFILE 'user.txt' FROM user;(报错 1290) - ⚠️ 注意:
LOAD DATA INFILE不接受LOCAL关键字绕过——LOAD DATA LOCAL INFILE受客户端控制,和secure_file_priv无关,但服务端默认禁用该功能
Docker 环境下最容易卡在挂载和路径映射
镜像启动时若没挂载对应目录,改配置也没用:
- 启动命令要带:
-v /host/export:/var/lib/mysql-files(假设容器内secure_file_priv是默认值) - 或者自定义路径:
-v /host/mydata:/mydata -e MYSQL_SECURE_FILE_PRIV=/mydata,再在配置里设secure_file_priv = /mydata - 别信“进容器里
touch一下就 OK”——MySQL 进程 UID 必须能写,ls -ld /mydata看属主
真正麻烦的从来不是改哪行配置,而是确认 MySQL 进程在操作系统层面到底有没有那个目录的写权限——这一步跳过,后面全白调。











