MySQL · 错误码速查
MySQL 错误 1290:报错里写的是哪个选项,就按哪个选项处理;secure-file-priv 先把文件放进允许的目录
1290 的报错里会写出是哪个启动选项拦的。写的是 --secure-file-priv:LOAD DATA、SELECT ... INTO OUTFILE 只能读写这个变量指定的目录,把文件放进去或改用 LOAD DATA LOCAL 即可,不需要把它改成空。写的是 --read-only / --super-read-only:你连到的是只读实例(常见于从库),写操作应该发到主库。
官方原文
The MySQL server is running with the %s option so it cannot execute this statement%s 是拦下语句的选项名,最常见的是 --secure-file-priv、--read-only 和 --super-read-only。
出处:MySQL 8.4 Error Reference:Server Error Message Reference 最后核对:
| 错误号 / 符号 | 1290 / ER_OPTION_PREVENTS_STATEMENT | 出处 |
|---|---|---|
| SQLSTATE | HY000 | 出处 |
| secure_file_priv 是否可在线修改 | 不可以(Dynamic: No),只能改配置后重启 | 出处 |
| DEB / RPM 安装包的默认值 | /var/lib/mysql-files | 出处 |
| local_infile 默认值 | OFF(服务端默认拒绝 LOAD DATA LOCAL) | 出处 |
第一步:看报错里写的是哪个选项
| 报错里的 %s | 常见语句 | 含义 |
|---|---|---|
--secure-file-priv | LOAD DATA INFILE、SELECT ... INTO OUTFILE、LOAD_FILE() | 服务器限制了能读写文件的目录,你给的路径不在里面,或者导入导出被整体禁用 |
--read-only | INSERT / UPDATE / DELETE / DDL | 实例是只读的,没有 CONNECTION_ADMIN(或已弃用的 SUPER)权限的用户不能写 |
--super-read-only | 同上 | 连有 CONNECTION_ADMIN / SUPER 权限的用户也不能写 |
SELECT @@GLOBAL.secure_file_priv,
@@GLOBAL.read_only,
@@GLOBAL.super_read_only,
@@GLOBAL.local_infile;secure_file_priv 的三种取值和处理办法
| 查到的值 | 官方含义 | 怎么做 |
|---|---|---|
一个目录,如 /var/lib/mysql-files/ | 导入导出只能用这个目录里的文件 | 把要导入的文件拷进这个目录(注意 mysqld 进程要有读权限);INTO OUTFILE 的路径也写到这个目录下 |
NULL | 导入导出功能整体禁用 | 改用客户端侧的 LOAD DATA LOCAL,或用 mysqldump / 客户端工具导出;要开启只能改配置并重启 |
| 空字符串 | 不做限制(官方说明这不是安全设置) | 一般不会报 1290;如果仍报,看报错里是不是别的选项 |
-- 假设查到的 secure_file_priv 是 /var/lib/mysql-files/
SELECT id, order_no, amount
FROM orders
WHERE created_at >= '2026-10-01'
INTO OUTFILE '/var/lib/mysql-files/orders_202610.csv'
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';secure_file_priv不能在线修改,SET GLOBAL会失败;要改只能写进配置文件后重启。- 官方提醒:值为空、指向数据目录或其子目录、或指向所有用户都能访问的目录,都被视为不安全,启动时会写警告;指向不存在的目录时服务器直接启动失败。
- Docker 官方镜像、云数据库的默认值可能和安装包不同,以
SELECT @@GLOBAL.secure_file_priv查到的为准。
不想动服务器配置:用 LOAD DATA LOCAL 从客户端读文件
LOAD DATA LOCAL INFILE 由客户端读取本机文件再发给服务器,不受 secure_file_priv 限制,也不需要 FILE 权限。但它要求服务端和客户端都允许 LOCAL:
- 服务端:
local_infile默认是OFF,需要 DBA 设为 ON(这个变量可以在线修改:SET GLOBAL local_infile = ON;)。 - 客户端:
mysql命令行要加--local-infile=1;各语言驱动有各自的开关。 - 两边任何一边没开,LOCAL 都会报错(不是 1290,而是提示 LOCAL 被禁用)。
mysql --local-infile=1 -h db.example.internal -u app -p appdb \
-e "LOAD DATA LOCAL INFILE '/home/app/orders.csv' INTO TABLE orders FIELDS TERMINATED BY ',' IGNORE 1 LINES;"开启 local_infile 有安全含义:被攻破的服务器可以要求客户端发送任意本地文件。官方在 Security Considerations for LOAD DATA LOCAL 里专门讨论了这个风险,用完可以再关上。
报的是 read-only:确认自己连的是不是从库
read_only 常用在复制从库上,保证从库只接受来自主库的复制更新。看到 --read-only 或 --super-read-only,先确认连接串指向的是不是主库,而不是把从库的只读关掉:
SELECT @@hostname, @@port, @@read_only, @@super_read_only;
SHOW REPLICA STATUS\G- 只读模式下仍允许:复制线程的更新、
ANALYZE TABLE/OPTIMIZE TABLE,以及临时表操作等少数例外。 - 设置
super_read_only=ON会自动把read_only也设为 ON;把read_only设为 OFF 会同时关掉super_read_only。 - 主从切换、云数据库维护后,原来的主库可能被设成只读;应用写入报 1290 时先查连接是否还指向旧主库。
常见问题
MySQL 1290 --secure-file-priv 怎么解决?
先 SELECT @@GLOBAL.secure_file_priv 查允许的目录,把要导入的文件放进去,或把 INTO OUTFILE 的路径写到这个目录下。值为 NULL 表示导入导出被禁用,可以改用客户端侧的 LOAD DATA LOCAL。
能不能用 SET GLOBAL 修改 secure_file_priv?
不能。secure_file_priv 不是动态变量,只能写进配置文件后重启 MySQL。官方也不建议设成空字符串,那等于不做限制。
LOAD DATA LOCAL 为什么也报错?
LOCAL 需要服务端 local_infile=ON(默认 OFF)并且客户端也开启(mysql 命令行加 --local-infile=1)。任何一边没开都会失败。
1290 read-only 是什么意思?
服务器开着 read_only 或 super_read_only,普通用户不能写。通常是连到了从库,或者主从切换后旧主库被设成了只读。先确认连接指向的是主库。
Windows 上 secure_file_priv 是什么路径?
不同安装方式默认值不同,以 SELECT @@GLOBAL.secure_file_priv 实际查到的为准。路径里的反斜杠在 SQL 里要写成正斜杠或双反斜杠。
下一步
价格以对应页面当前标价为准。
出处(最后核对 2026-11-04)
- MySQL 8.4 Error Reference:Server Error Message Reference
- MySQL 8.4 Reference Manual:Server System Variables(secure_file_priv、read_only、local_infile)
- MySQL 8.4 Reference Manual 15.2.9:LOAD DATA Statement
- MySQL 8.4 Reference Manual 8.1.6:Security Considerations for LOAD DATA LOCAL
本页摘录并解读上面列出的官方文档,不是官方页面;官方文档更新后以官方为准。本页内容都来自官方文档,没有我们自己的测试结果。