OUTFILE 在服务端落盘
SELECT ... INTO OUTFILE 让数据库进程把结果集直接写成服务器本地文件,不经过客户端。它适合把大结果集落盘归档,或配合 LOAD DATA 做同构实例之间的数据搬运,省掉客户端往返与内存开销。代价是文件写在数据库主机上,受 secure_file_priv 目录白名单与 FILE 全局权限双重限制,云数据库多数直接禁用。
基本信息
| 适用平台 | MySQL 5.7 / 8.0(MariaDB 语法兼容) |
|---|---|
| 语法 | SELECT 列 ... INTO OUTFILE '/绝对路径/文件' 导出选项 |
| 权限要求 | 全局 FILE 权限,且路径要落在 secure_file_priv 目录内 |
| 文件行为 | 文件必须不存在,已存在会直接报错而不覆盖 |
| 相关语句 | INTO DUMPFILE 只写单行无分隔符;LOAD DATA 可回读 |
| 编码 | 可用 CHARACTER SET 指定导出字符集 |
典型使用场景
- 按时间把历史数据导出成 CSV,交给下游归档或数仓
- 跨实例搬数据:先落盘再压缩传输,避免客户端成为瓶颈
- 向审计或法务交付固定格式的文本快照
- 结果集远超客户端内存时先把中间结果写到服务器磁盘
- 给离线分析准备中间文件,避免几百万行结果压爆客户端
使用与诊断
使用与诊断
# 先确认白名单目录:空串表示禁止,NULL 表示不限制
SHOW VARIABLES LIKE 'secure_file_priv';
SELECT id, sku, qty FROM orders
WHERE created_at >= '2026-10-01' AND created_at < '2026-11-01'
INTO OUTFILE '/var/lib/mysql-files/orders_202610.csv'
CHARACTER SET utf8mb4
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';
# 制表符分隔的写法
SELECT * FROM t INTO OUTFILE '/var/lib/mysql-files/t.tsv'
FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n';
# 给 Windows 侧打开时改行尾
SELECT * FROM t INTO OUTFILE '/var/lib/mysql-files/t_crlf.csv'
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n';
# 回读校验,目标表需已存在
LOAD DATA INFILE '/var/lib/mysql-files/t.tsv' INTO TABLE t;导出子句速查
| 关键字 | 作用 | 默认与注意 |
|---|---|---|
| FIELDS TERMINATED BY | 列分隔符 | 默认制表符 |
| OPTIONALLY ENCLOSED BY | 字符串列加包围符 | 数值列不受影响 |
| ESCAPED BY | 转义字符 | 默认反斜杠 |
| LINES TERMINATED BY | 行分隔符 | 默认换行符,Windows 需回车加换行 |
| LINES STARTING BY | 行前缀 | 可跳过带特定前缀的行 |
| CHARACTER SET | 导出文件编码 | 显式指定最省事 |
导出文件的属主通常是运行 mysqld 的账号(如 mysql),权限受 umask 影响,其他账号未必读得到;导出前先确认服务器磁盘余量,导出后尽快搬走,不要长期堆在数据目录附近。
secure_file_priv 为 NULL 表示不限制任何路径,配上已授出的 FILE 权限等于允许写任意目录,属于高危配置,绝不要为省事长期保留;不少云数据库直接禁用 FILE 权限,方案评审前先验证环境是否支持。