mysqldump必须同时显式指定--routines和--triggers才能完整备份存储过程、函数及触发器,二者互不包含、不可替代;仅加其一将导致对应对象静默缺失,且需配合库名使用,权限不足或definer问题亦会导致导出失败。

mysqldump --routines --triggers 必须成对出现
只加 --routines 不加 --triggers,或反过来,都会导致对应对象缺失——--routines 管存储过程和函数,--triggers 单独控制触发器,二者互不包含。常见错误是导出后发现触发器没进文件,却反复检查 --routines 是否拼错。
实操要点:
-
--routines和--triggers必须同时显式指定,不能依赖默认值 - 必须搭配库名使用,例如
mysqldump --routines --triggers mydb;单独写mysqldump mydb什么高级对象都不会导出 - 若目标是“只导过程+触发器,不要表结构和数据”,用
--no-data --no-create-info组合,但注意:MySQL 5.6 某些版本下--no-create-info会连带跳过触发器,稳妥起见可改用--skip-triggers反向验证是否生效
权限不足时 mysqldump 静默丢对象,不是报错就完事
执行命令返回成功、文件也生成了,但打开一看没有 CREATE PROCEDURE 或 CREATE TRIGGER ——这大概率是权限问题。MySQL 5.7+ 要求用户至少有 SUPER 权限(8.0+ 可用 BACKUP_ADMIN),否则 mysqldump 读 mysql.proc 或 information_schema.ROUTINES 时失败,但不会中断流程,而是跳过这部分内容。
判断方式:
- 用
root账号跑一次,对比输出文件大小和内容差异 - 检查错误日志里是否有
Access denied; you need (at least one of) the SUPER or SELECT privilege(s) - 云数据库(如阿里云 RDS、AWS RDS)默认禁用
SUPER,此时应改用SHOW CREATE方式绕行
导入时 ERROR 1418:DEFINER 是最常被忽略的兼容性雷区
从 A 库导出的存储过程带 DEFINER='app@10.%.%',导入 B 库时报 ERROR 1418,根本原因是目标库不存在该用户,或当前登录用户无 SET_USER_ID 权限。这不是语法错误,而是安全策略拦截。
快速应对方案:
- 导出时加
--skip-definer,让mysqldump自动移除DEFINER=子句,改用当前登录用户作为隐式定义者(不影响SQL SECURITY行为) - 生产环境建议提前在目标库执行
CREATE USER 'app'@'10.%.%' IDENTIFIED BY 'xxx'; GRANT ...,再导入 - 别用
--force强行跳过——它只会让过程/触发器彻底丢失,且不提示
批量导出单个对象?别硬套 mysqldump,用 SHOW CREATE 更稳
如果只要导出 p_update_cache 和 t_log_insert 这两个对象,而不是整个库的所有过程/触发器,mysqldump 就不是最优解。它不支持 --procedure=p_update_cache 这类粒度,强行全量导出再 grep 容易跨行截断、漏掉换行符、受注释干扰。
推荐做法:
- 对每个过程:运行
mysql -u user -p -e "SHOW CREATE PROCEDURE mydb.p_update_cache" > p_update_cache.sql - 对每个触发器:必须带库名前缀,
mysql -u user -p -e "SHOW CREATE TRIGGER mydb.t_log_insert" > t_log_insert.sql - 批量生成脚本可用
information_schema查询拼接,但要注意:ROUTINE_DEFINITION在 MySQL 8.0+ 默认不可见(需show_create_routine权限),而ACTION_STATEMENT不含CREATE TRIGGER头部,得手动补全
真正麻烦的从来不是命令怎么敲,而是导出后发现某段逻辑在目标库执行报错——那往往是因为 DEFINER、SQL SECURITY 或时区/字符集隐式依赖没被显式处理。











