mysqldump -R 不导出存储过程,主因是权限不足(缺 EXECUTE 或 SHOW ROUTINES)或参数未配合库名/--databases使用;-R 必须与库名共用,且需 --no-data --no-create-info --skip-definer 组合才能精准导出纯净逻辑对象。

mysqldump -R 不导出存储过程?先查权限和参数组合
加了 -R(即 --routines)却没在备份文件里看到 CREATE PROCEDURE 或 CREATE FUNCTION,大概率不是命令写错了,而是权限或参数位置不对。
关键点:
-
-R必须与库名或--databases一起用,单独写mysqldump -u root -p -R无效 - 用户需同时具备:
SELECT+SHOW ROUTINES+EXECUTE权限(注意:EXECUTE是必须的,不是可选) - MySQL 5.6 默认关闭
-R,5.7+ 默认开启但依赖权限;跨版本迁移脚本时容易漏掉权限校验 - 验证是否生效:用
grep -i "create procedure\|create function" backup.sql | head -2查看输出
--triggers 导出触发器但恢复失败?DEFINER 是罪魁祸首
--triggers 会原样导出 CREATE DEFINER=`user`@`host` TRIGGER,而目标库若无该用户、或该用户没 TRIGGER 权限,就会报 ERROR 1418 或 Access denied——这不是语法错,是权限继承失败。
正确做法:
- 导出时加
--skip-definer(MySQL 5.7.8+ 支持),让 mysqldump 自动剥离所有DEFINER子句 - 不要用
sed手动替换,容易误伤注释或字符串里的@ - 如果必须保留 DEFINER,确保目标库存在对应用户且已授
TRIGGER权限 -
--triggers在单表导出时默认开启,但在--databases或全库场景下必须显式声明,否则可能被跳过
只导特定存储过程和触发器?mysqldump 不支持按名称过滤
mysqldump 没有 --routines=proc_name 或 --triggers=trigger_name 这类参数。所谓“特定”,只能靠事后提取或换工具。
实操路径:
- 先全量导出:
mysqldump -u root -p --no-data --routines --triggers mydb > all_routines_triggers.sql - 提取存储过程:
grep -A 50 "^DELIMITER.*$$" all_routines_triggers.sql | grep -E "^CREATE PROCEDURE|^DELIMITER" | sed '/^$$/d' - 提取触发器:
grep -A 30 "CREATE DEFINER.*TRIGGER" all_routines_triggers.sql - 更可靠方案:用
mysqlpump --routines --exclude-tables=% mydb(MySQL 5.7+),它支持逻辑对象粒度控制
-t 参数和存储过程/触发器完全无关,别混用
-t 是 --no-create-info 的简写,只影响是否输出 INSERT 语句,对 routines 和 triggers 的导出毫无作用。很多人以为 -R -t 能“只导逻辑对象”,结果发现文件里仍有大量 CREATE TABLE —— 因为 -t 不屏蔽建表语句。
真正需要的是:
-
--no-data:跳过所有INSERT(数据) -
--no-create-info:跳过所有CREATE TABLE(结构) - 但即使两者都加,
CREATE PROCEDURE和CREATE TRIGGER仍会保留——这才是你想要的 - 最终干净命令示例:
mysqldump -u root -p --no-data --no-create-info --routines --triggers --skip-definer mydb > logic_only.sql
最容易被忽略的一点:--routines 和 --triggers 都不检查对象是否存在,只要权限够、参数对,就全量导出库内所有 routine 和 trigger。想精确到某一个,只能靠导出后文本处理或改用 SHOW CREATE PROCEDURE 手动抓取。


















