FILE权限必须用GRANT FILE ON .授予,属全局管理权限,不可限定库或表;否则报ERROR 1221;还需配合secure_file_priv路径限制及SELECT/INSERT等操作权限。

FILE权限必须用 GRANT FILE ON *.* 授予
MySQL 的 FILE 权限是全局管理权限,不能限定到库、表或列。试图执行 GRANT FILE ON mydb.* TO 'u'@'%' 会直接报错。它只允许搭配 *.* 使用,因为该权限本质是让账号能读写服务器文件系统,与具体数据库结构无关。
常见错误现象:
-
ERROR 1221 (HY000): Incorrect usage of DBA privilege and—— 出现在用了非FILE*.*作用域时 -
ERROR 1045 (28000): Access denied for user—— 权限未生效或未FLUSH PRIVILEGES
正确操作步骤:
- 登录 MySQL(需有
GRANT OPTION权限) - 执行
GRANT FILE ON *.* TO 'your_user'@'localhost' - 立即执行
FLUSH PRIVILEGES - 用
SHOW GRANTS FOR 'your_user'@'localhost'确认输出中含GRANT FILE ON *.*
LOAD DATA LOCAL INFILE 需客户端和服务端双重启用
仅授 FILE 权限还不够:LOAD DATA LOCAL INFILE 是客户端发起、服务端接收的流程,两端都得“点头”。服务端默认禁用,客户端默认不发送。
容易踩的坑:
- 服务端没开
local_infile=1→ 报错ERROR 1148 (42000): The used command is not allowed with this MySQL version - 客户端命令行未加
--local-infile=1→ 同样报 1148,且不会提示原因 - 服务端编译时未带
--enable-local-infile→ 即使配置了也无效,只能重装或换包
实操建议:
- 服务端:在
/etc/my.cnf的[mysqld]段加local_infile=1,重启 mysqld - 客户端连接时显式启用:
mysql --local-infile=1 -u user -p db_name - 应用代码里(如 Python PyMySQL)需在
connect()中传local_infile=True
LOAD DATA INFILE 要求文件在服务端且路径受限
去掉 LOCAL 关键字后,LOAD DATA INFILE 会直接从 MySQL 服务端读取文件。这意味着:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 文件必须真实存在于服务器磁盘上,不能是客户端路径
- MySQL 进程用户(如
mysql)必须对文件有读权限 - MySQL 默认只允许读取
secure_file_priv指定目录下的文件(查法:SELECT @@secure_file_priv)
典型错误:
-
ERROR 13 (HY000): Can't get stat of '/path/to/file.csv' (Errcode: 13 - Permission denied)—— 文件权限或secure_file_priv限制导致 -
ERROR 29 (HY000): File '/xxx' not found—— 文件不在secure_file_priv目录内,或路径拼错
绕过方式(不推荐生产环境):
- 把文件拷到
@@secure_file_priv返回的路径下(如/var/lib/mysql-files/) - 临时改配置:
SET GLOBAL secure_file_priv = ''(需 SUPER 权限,且重启后失效)
FILE 权限是高危权限,不是“导入数据专用”
很多人以为 FILE 权限只影响 LOAD DATA 和 SELECT INTO OUTFILE,其实它还控制 LOAD_FILE() 函数——这个函数能读任意服务器上 MySQL 进程可读的文件。
真实风险场景:
- 攻击者用
SELECT LOAD_FILE('/etc/passwd')直接读取系统用户列表 - 用
LOAD DATA INFILE '/var/lib/mysql/mydb/tbl.MYD'尝试导出 MyISAM 表原始数据文件 - 配合
SELECT ... INTO OUTFILE写 Webshell 到网站目录(如果 MySQL 用户对 web 目录有写权限)
所以关键提醒:
- 永远不要给非 DBA 账号授予
FILE权限 - 生产环境服务端应设
local_infile=0(除非明确需要客户端导入) - 检查
secure_file_priv是否为NULL或空字符串,若非必要,应设为最小化目录
权限一旦放开,就不再是“能不能导入 CSV”的问题,而是“能不能读服务器上所有可读文件”的问题。










