mysqldump --no-create-info 仍报 drop 权限错误,因默认启用 --add-drop-table,需显式加 --skip-add-drop-table;确保纯 insert 需组合使用 --no-create-info --skip-add-drop-table --skip-add-locks --skip-disable-keys。
为什么 mysqldump --no-create-info 仍会报 drop 权限错误
因为默认情况下 mysqldump 即使不导出建表语句,也会在 insert 前尝试加 drop table if exists(受 --add-drop-table 控制),而该选项默认开启。只要没显式关掉,就会触发权限检查——哪怕你根本不需要它。
实操建议:
- 必须显式加
--skip-add-drop-table,不能只靠--no-create-info - 如果还用了
--databases或--all-databases,额外加上--skip-add-locks和--skip-disable-keys,它们也会隐式依赖写权限 - 验证是否生效:导出后 grep 一下输出里有没有
DROP TABLE,有就是没关干净
怎样确保只导出纯 INSERT 不带任何 DDL
核心是切断所有可能生成 DDL 的开关,不是“不想要建表语句”就完事了——mysqldump 的 DDL 行为分散在多个参数里。
实操建议:
- 必加组合:
--no-create-info --skip-add-drop-table --skip-add-locks --skip-disable-keys - 避免用
--databases,改用直接指定表名,例如:mysqldump -u user -p db_name table1 table2,否则某些版本会在开头加CREATE DATABASE注释(虽不执行,但部分严格权限策略会拦截) - 若目标是兼容低权限账号,再加
--compact --skip-triggers --skip-routines --skip-events,排除所有可能引入非 INSERT 的内容
导出脚本里出现 SET FOREIGN_KEY_CHECKS=0 怎么办
这个语句本身不需 DROP 权限,但它是 mysqldump 为绕过外键约束自动加的——而有些环境会把 SET 操作也纳入权限管控(尤其启用了 sql_mode=STRICT_TRANS_TABLES 或审计插件时)。
实操建议:
- 加
--skip-set-charset并配合--default-character-set=utf8mb4(显式指定而非让服务端推断)可减少意外 SET - 更彻底的办法:用
--tab模式导出纯数据文件(CSV/TSV),再用LOAD DATA INFILE导入,完全绕过 SQL 解析层——但要求有文件系统写权限且目标库开local_infile - 如果只能走 SQL 文件,导出后用 sed 删除:
sed '/^SET FOREIGN_KEY_CHECKS/d' dump.sql > clean.sql
权限不足时用 SELECT ... INTO OUTFILE 替代的注意事项
这是真正绕过 DROP、CREATE 等 DDL 权限的方案,但 INTO OUTFILE 本身需要 FILE 权限,且文件写在数据库服务器本地,不是客户端。
实操建议:
- 确认用户有
FILE权限:SHOW GRANTS FOR CURRENT_USER; -
SELECT * FROM table INTO OUTFILE '/tmp/table.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY ' ';—— 路径必须是服务端绝对路径,且 MySQL 进程有写权限 - 导出的 CSV 没有 INSERT 包裹,导入时得用
LOAD DATA INFILE,注意目标库也要开local_infile,且路径是服务端视角 - 日期、NULL、换行符等字段内容容易破坏 CSV 格式,务必加
ESCAPED BY '\'并测试小样本
最常被忽略的是:INTO OUTFILE 无法跨库导出视图或带函数的列,也不支持分页导出大表——这时候要么分批查,要么老实用 mysqldump 配好参数,别硬扛权限限制。










