MySQL INTO OUTFILE 报错 ERROR 1290 源于 secure_file_priv 限制与 FILE 权限缺失:需先查 @@secure_file_priv 值,再授 FILE 权限、限定导出路径、处理字段转义,并优先考虑客户端重定向等替代方案。

mysql INTO OUTFILE 权限不足导致报错 ERROR 1290 (HY000)
MySQL 默认禁用 INTO OUTFILE,除非显式开启 secure_file_priv 并赋予用户 FILE 权限。没配好直接执行会卡在权限拒绝上,不是语法错,是服务端策略拦截。
- 先查当前限制:
SELECT @@secure_file_priv;—— 如果返回NULL或空字符串,说明该功能被完全禁用,改配置文件也无效 - 若返回路径(如
/var/lib/mysql-files/),则INTO OUTFILE只能写入该目录,且文件名不能带路径,只允许 basename(例如'data.csv',不能写'./out/data.csv') - 给用户加权限:
GRANT FILE ON *.* TO 'your_user'@'host'; FLUSH PRIVILEGES;—— 注意这是全局权限,无法按库或表粒度控制
导出 CSV 格式时字段分隔符和换行处理不一致
MySQL 不自动转义字段内的换行、逗号或双引号,INTO OUTFILE 输出的是裸文本,直接用 Excel 打开大概率错列。它只按你指定的 FIELDS TERMINATED BY 和 LINES TERMINATED BY 拆分,不做内容清洗。
- 安全做法:强制用双引号包裹所有字段,加
OPTIONALLY ENCLOSED BY '"' - 避免换行破坏结构:确保查询结果中字段不含
\n,可用REPLACE(col, '\n', ' ')预处理 - 典型导出语句:
SELECT id,name,email FROM users INTO OUTFILE '/var/lib/mysql-files/users.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';
替代方案:用 mysqldump 或客户端重定向更可控
INTO OUTFILE 必须在 MySQL 服务端执行,且依赖服务器磁盘权限;而很多场景其实只需要把查询结果落地为 CSV,不一定非得走服务端写文件。
- 命令行导出(推荐):
mysql -u user -p -e "SELECT * FROM t" db_name > output.csv—— 简单、无权限限制、可管道加工 - 加格式化(制表符分隔,适合后续 awk/sed 处理):
mysql -B -u user -p -e "SELECT * FROM t" db_name | sed 's/\t/,/g' > output.csv - 如果必须服务端生成且要兼容 Excel,优先考虑应用层导出(比如 Python 的
pandas.to_csv()+to_sql()查询),而不是硬扛INTO OUTFILE的边界条件
导出大表时卡住或中断,没有进度反馈
INTO OUTFILE 是同步阻塞操作,期间连接不能干别的,也没回调机制。查 500 万行时你只能等,中间断连就前功尽弃,还可能因超时触发 wait_timeout 自动断开。
- 导出前调大会话级超时:
SET SESSION wait_timeout = 3600; - 避免 SELECT *,只选必要字段,减少内存和 IO 压力
- 对超大表,拆成多个
WHERE id BETWEEN x AND y分段导出,再合并 ——INTO OUTFILE本身不支持追加,每次都是覆盖
导出路径、权限、字段转义、客户端替代方式这四点,漏掉任何一个都容易卡在“明明语句没错却导不出”。特别是 secure_file_priv 的值,很多人查都不查就去改 my.cnf,其实它可能已经被启动参数硬编码覆盖了。










