必须组合参数才能只导出routine和trigger:mysqldump --no-create-info --no-data --routines --triggers最常用,但会混入视图;mysqlpump --routines --exclude-tables=%更精准,仅限MySQL 5.7+;手动SHOW CREATE适合单对象备份。

不能靠 mysqldump 一个参数就“只导出 routine 和 trigger”,必须组合参数或换工具,否则会混入表结构或数据。
用 mysqldump --no-create-info --no-data --routines --triggers 导出纯逻辑对象
这是最常用、兼容性最好的方式,但要注意它仍会导出视图(VIEW)和事件(EVENT)——如果没加 --events,事件不会出现;但视图默认随库导出,且无法单独禁用。
-
--no-create-info关掉 CREATE TABLE / CREATE DATABASE 语句,避免表结构干扰 -
--no-data确保不导任何 INSERT,只留定义 -
--routines导出所有 PROCEDURE 和 FUNCTION(无法只选某几个) -
--triggers导出所有 TRIGGER(同样无法按名过滤,且触发器绑定在原表名上) - 命令示例:
mysqldump -u root -p --no-create-info --no-data --routines --triggers mydb > logic_only.sql - 常见坑:若目标库表不存在,导入
logic_only.sql时 CREATE TRIGGER 会报错ERROR 1356 (HY000): Trigger does not exist on table 'xxx',因为触发器定义依赖表已存在
用 mysqlpump --routines --exclude-tables=% 只留 routine 类对象
MySQL 5.7+ 自带的 mysqlpump 比 mysqldump 更适合这类需求,它能真正排除所有表、视图、事件等,只保留存储过程、函数、触发器。
-
--routines启用 routine 导出(含 PROCEDURE/FUNCTION/TRIGGER) -
--exclude-tables=%是关键:通配符 % 表示排除所有表(包括视图、事件),但 routine 不受影响 - 命令示例:
mysqlpump --user=root --password --routines --exclude-tables=% mydb > routines_and_triggers.sql - 注意:
mysqlpump不支持--skip-definer,如需剥离 DEFINER,得后续用sed 's/DEFINER[^\*]*\*/\*/g'处理 - 兼容性限制:MySQL 5.6 及更早版本不支持
mysqlpump,别在旧环境硬套
手动提取单个存储过程或触发器定义(精确控制场景)
当只需要备份一两个关键对象(比如灰度发布前的 t_audit_insert 触发器),SHOW CREATE 是唯一可靠、零依赖的方法。
-
SHOW CREATE PROCEDURE和SHOW CREATE TRIGGER返回的是可执行 SQL,但缺DELIMITER声明 - 必须人工补上,否则
source会因分号提前终止而报错ERROR 1064 - 触发器名必须带库名前缀:
SHOW CREATE TRIGGER mydb.t_audit_insert;,否则报ERROR 1360 (HY000): Trigger does not exist - 重定向保存示例:
mysql -u root -p -e "SHOW CREATE PROCEDURE mydb.calc_total;" > proc_calc_total.sql - 导出后记得手动编辑文件头尾:开头加
DELIMITER $$,结尾加$$和DELIMITER ;
为什么 grep/sed 提取全量备份里的对象容易出错
很多人想先 dump 全库再用文本工具切块,但实际中极易漏掉跨行定义、被注释掩盖、或匹配到函数体内的字符串。
-
grep -A 50 "CREATE DEFINER.*PROCEDURE"可能截断长过程体,尤其含多层 BEGIN/END 嵌套时 - 触发器定义块常以
CREATE DEFINER ... TRIGGER `name` ON `table`开头,但中间可能含换行、空格、反引号转义,简单正则不稳 - 更稳妥的是用
sed -n '/^CREATE DEFINER.*TRIGGER `t_name`/,/^$$/p',但它依赖导出时已用$$作分隔符(mysqldump默认用;;,需额外加--delimiter="$$") - 真正批量操作建议写 Python 脚本解析 SQL AST,而不是靠 shell 文本处理——后者在生产环境风险太高
最容易被忽略的一点是:无论用哪种方式导出,只要涉及 DEFINER,目标库用户就必须有 SET USER 权限或提前清理 DEFINER;MySQL 8.0+ 还要确认 event_scheduler 是否开启(影响 EVENT 导入),而这些细节在导出阶段完全不体现,只能靠经验预判。


















