secure_file_priv 是 mysql 强制启用的安全限制,限定 load data 和 select ... into outfile 的文件操作仅能在指定目录进行;设为非空路径则路径必须严格匹配,设为 null 则完全禁止,空字符串已弃用且危险。

secure_file_priv 是什么,为什么它会阻止你的 LOAD DATA 或 SELECT ... INTO OUTFILE
它不是可选开关,而是 MySQL 强制启用的安全围栏:当 secure_file_priv 被设为非空路径(比如 /var/lib/mysql-files/),所有文件导入导出操作只能在这个目录下进行。你执行 LOAD DATA INFILE '/tmp/data.csv' 却报错 ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option...,根本原因就在这里——路径越界了。
它默认值在不同发行版里不一致:MySQL 8.0 官方二进制包默认是 /var/lib/mysql-files/,而某些 Docker 镜像或 macOS Homebrew 安装可能设为 NULL(完全禁用)或空字符串(危险开放,已弃用)。
- 设为
NULL→ 所有导入导出命令直接报错,连SHOW VARIABLES LIKE 'secure_file_priv'都返回 NULL - 设为空字符串(
'')→ 允许任意路径(5.7 以前常见,8.0+ 启动会警告,不推荐) - 设为具体目录(如
/data/mysql-import/)→ 唯一合法路径,且 MySQL 进程必须对该目录有读写权限
怎么查当前值、改配置、让修改生效
先确认现状:SELECT @@secure_file_priv; 比 SHOW VARIABLES 更直接,返回值就是最终生效值。别只看 my.cnf 里写了啥——动态加载或启动参数可能覆盖它。
- 修改必须在 MySQL 配置文件(如
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf)的[mysqld]段落下加:secure_file_priv = /data/mysql-files/ - 不能用
SET GLOBAL secure_file_priv = ...动态修改,该变量是只读的,运行时无法变更 - 改完必须重启 MySQL:直接
systemctl restart mysql,别只 reload;否则配置不生效 - 新目录需手动创建,并确保
mysql用户(不是 root)有读写权限:sudo mkdir -p /data/mysql-files && sudo chown mysql:mysql /data/mysql-files
LOAD DATA 和 SELECT ... INTO OUTFILE 的路径必须严格匹配 secure_file_priv
哪怕只差一个点、多一个斜杠,都会失败。MySQL 不做路径解析或软链接展开,只做字面量前缀匹配。
-
secure_file_priv = /var/lib/mysql-files/→ 允许LOAD DATA INFILE '/var/lib/mysql-files/data.csv',但不允许'/var/lib/mysql-files/sub/data.csv'(除非你显式设为/var/lib/mysql-files/并确保子目录存在且权限正确) - 绝对路径是唯一支持形式,相对路径(如
./data.csv)直接报错 - Windows 下注意反斜杠转义问题:
LOAD DATA INFILE 'C:\temp\data.csv',但更稳妥的是统一用正斜杠:'C:/temp/data.csv' -
SELECT ... INTO OUTFILE写出的文件,MySQL 不会自动覆盖同名文件,会直接报错ERROR 1086 (HY000),得先手动清理
绕过 secure_file_priv 的替代方案(不推荐但有时不得不做)
真要从任意路径读 CSV?别硬改 secure_file_priv 开后门。优先走应用层处理:
- 用客户端工具(如
mysqlimport命令行)代替LOAD DATA:它走网络协议上传,不受服务端文件路径限制 - 用 Python/Node.js 等读取本地 CSV,逐批
INSERT—— 慢但可控、可加事务、可做清洗 - Docker 场景下,把文件挂载到
secure_file_priv指定目录再操作,比如-v $(pwd)/data:/var/lib/mysql-files - 临时调试?停掉 MySQL,启动时加
--secure-file-priv=(空值),仅限本地开发环境,切勿上生产
最常被忽略的一点:MySQL 用户权限和 OS 文件权限是两层独立校验。即使 secure_file_priv 放开了路径,mysql 进程用户没权限读那个文件,照样报错——错误信息还是一样的 ERROR 1290,容易误判。











