第一步是执行SHOW VARIABLES LIKE 'secure_file_priv';确认当前值,结果只有NULL(禁用)、具体路径(仅限该目录读写)或空字符串''(不限制但需注意系统权限)三种可能。

查当前 secure_file_priv 值是第一步
不先确认当前值,直接改配置容易白忙活。进 MySQL 执行:
show variables like 'secure_file_priv';
返回结果只有三种可能:NULL、一个具体路径(如 /var/lib/mysql-files/)、或空字符串 ''。三者行为完全不同:
-
NULL:所有LOAD DATA INFILE、SELECT ... INTO OUTFILE、LOAD_FILE()全部被禁用,报错[Code: 1290, SQL State: HY000] - 具体路径(如
/tmp/):只能在该目录下读写文件,且该目录必须存在、MySQL 进程(通常是mysql用户)有读写权限 - 空字符串
'':不限制路径——但注意,这只是“不限制 MySQL 层面”,Linux 文件系统权限仍起作用
修改配置文件比命令行参数更可靠
临时用 mysqld --secure-file-priv=/tmp 启动虽快,但服务重启后失效。生产环境必须改配置文件:
- 找到 MySQL 配置文件,常见位置:
/etc/my.cnf、/etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu)、C:ProgramDataMySQLMySQL Server X.Xmy.ini(Windows) - 在
[mysqld]段落下添加一行:secure_file_priv = /tmp/(Linux)或secure_file_priv = "D:\mysql_files\"(Windows,注意双反斜杠或正斜杠) - 不要写成
secure_file_priv = "/"或secure_file_priv = ""——前者在某些版本会因权限问题启动失败,后者虽等效于“不限制”,但部分 MySQL 版本(尤其 8.0+)会警告Insecure configuration - 保存后必须重启 MySQL 服务:
systemctl restart mysqld(Linux)或 Windows 服务管理器中重启
目录权限和路径细节最容易踩坑
即使配置写了 /mydata/,MySQL 仍可能报 Failed to access directory for --secure-file-priv:
- 目录必须真实存在,MySQL 不会自动创建 —— 先手动
mkdir /mydata - MySQL 进程用户(通常是
mysql)必须对目录有读、写、执行(rwx)权限:chown mysql:mysql /mydata && chmod 755 /mydata - 路径末尾不加斜杠(
/mydata✅,/mydata/❌)在部分旧版本会导致启动失败,建议统一不加 - SELinux(CentOS/RHEL)或 AppArmor(Ubuntu)可能拦截访问,临时关闭测试:
setenforce 0;确认是它拦的,再配策略而非永久关
导出时路径必须严格匹配 secure_file_priv
SELECT * FROM t INTO OUTFILE '/tmp/t.csv' 能成功,不代表 INTO OUTFILE '/home/mysql/t.csv' 就能跑 —— 即使你有 root 权限,MySQL 也只认配置里那个路径:
- 如果
secure_file_priv是/tmp/,那INTO OUTFILE的路径必须以/tmp/开头,比如/tmp/a.csv、/tmp/sub/b.csv - 不能用相对路径、符号链接跳转、或上级目录(
../)绕过限制 - 导入同理:
LOAD DATA INFILE '/tmp/data.csv'可行;LOAD DATA INFILE '/home/data.csv'直接报 1290 错误,不会提示“权限不够”,而是“不允许执行该语句”
真正麻烦的不是设不设,而是设完之后忘了检查目录是否存在、属主是否正确、SELinux 是否挡路——这些地方一卡,就容易以为配置没生效。


















