mysqldump --routines --triggers 必须指定库名(如 --databases mydb)且需 super/backup_admin 权限,否则静默跳过;需加 --skip-definer、--default-character-set=utf8mb4、--hex-blob 避免导入失败。

必须用 mysqldump 加 --routines 和 --triggers,但仅加这两个参数还不够——不指定库名或表名、权限不足、字符集/DEFINER 问题都会导致导出失败或内容缺失。
为什么 mysqldump --routines --triggers 却没导出任何过程或触发器?
这是最常踩的坑:参数本身没错,但执行上下文缺失关键条件。
-
mysqldump默认只处理表,--routines和--triggers是“开关”,不是“自动扫描器”——必须明确告诉它作用范围,比如用--databases mydb或直接写mydb(不能只写--all-databases且不带--routines) - 权限不够会静默跳过:需要
SUPER(5.7)或BACKUP_ADMIN(8.0),普通账号即使有SELECT也不行;RDS 类托管服务默认禁用SUPER,此时只能换用SHOW CREATE方式 - 如果只导库名(如
mysqldump --routines --triggers mydb),某些 5.7 版本在无表名时会漏掉触发器——稳妥做法是显式加--databases或补上任意一个表名(如mysqldump --routines --triggers mydb dummy_table)
如何安全导出并避免 DEFINER 和字符集报错?
导出文件里带 DEFINER=`user`@`host` 和非 UTF8MB4 字符集,会导致目标库导入失败。
- 加
--skip-definer去掉 DEFINER 行,让导入时自动使用当前用户(开发/测试环境推荐) - 显式指定字符集:
--default-character-set=utf8mb4,避免mysqldump用客户端默认字符集(如 latin1)导致中文注释乱码 - 加上
--hex-blob,防止 BLOB 字段导出为不可见控制字符,影响后续grep或编辑 - 完整命令示例:
mysqldump --routines --triggers --databases mydb --skip-definer --default-character-set=utf8mb4 --hex-blob -u root -p > mydb_routines.sql
批量导出多个库的过程和触发器,但不想导表结构和数据?
用 --no-data 会把表结构也干掉,而你只想留 routine 和 trigger ——正确组合是 --no-data --no-create-info。
-
--no-data:跳过 INSERT 语句(数据) -
--no-create-info:跳过 CREATE TABLE(表结构),但保留 CREATE PROCEDURE / CREATE TRIGGER - 注意:触发器仍绑定在原表名上,所以 dump 文件里会有类似
CREATE TRIGGER `mydb`.`t_log`这样的语句,导入前需确保目标库存在同名表,否则报错ERROR 1360 - 命令示例:
mysqldump --routines --triggers --no-data --no-create-info --databases db1 db2 --skip-definer -u root -p > routines_only.sql
当 mysqldump 不可用(如 RDS 权限受限)时,用 SHOW CREATE 批量生成脚本
这是唯一不依赖 SUPER 权限、兼容所有 MySQL 5.7+ 的兜底方案,但需手动拼接 DELIMITER。
- 先查出所有触发器:
SELECT CONCAT('SHOW CREATE TRIGGER `', TRIGGER_SCHEMA, '`.`', TRIGGER_NAME, '`;') FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA IN ('db1','db2'); - 把结果复制执行,或用 shell 导出:
mysql -u user -p -Nse "SELECT CONCAT('SHOW CREATE TRIGGER `', TRIGGER_SCHEMA, '`.`', TRIGGER_NAME, '`;') FROM ..." | mysql -u user -p > triggers.sql - 每个
SHOW CREATE TRIGGER输出不含DELIMITER,必须在每段前加DELIMITER $$,结尾加$$;否则 source 时遇到第一个分号就终止 -
存储过程同理,用
information_schema.ROUTINES查ROUTINE_TYPE = 'PROCEDURE',再拼SHOW CREATE PROCEDURE
真正麻烦的从来不是“怎么导”,而是导出来能不能直接 source。DEFINER、表依赖、DELIMITER 缺失、字符集混用——这些细节不提前处理,导入时就会卡在第一行。











