必须按需关闭触发器而非全关:若迁移脚本对触发器监控表执行insert/update/delete,则需禁用;sql server用disable trigger all on table_name,mysql需drop后重建并导出定义,且mysqldump须显式加--triggers参数。

需要关闭,但不是无差别全关——关键看迁移脚本是否会对触发器所监控的表执行 DML 操作。
迁移脚本里有 INSERT/UPDATE/DELETE 就必须关
如果迁移脚本包含 INSERT INTO target_table SELECT ... FROM source_table 这类语句,而 target_table 上定义了 AFTER INSERT 触发器,那它会在每条插入时被调用。一旦触发器里含日期校验、跨表查询或调用已失效函数(比如旧版 GETDATE()),就会直接中断迁移。
- SQL Server:用
DISABLE TRIGGER ALL ON table_name关单表所有触发器;别用DROP TRIGGER,恢复成本高 - MySQL:没有
DISABLE语法,得用DROP TRIGGER IF EXISTS trigger_name+ 提前导出定义(SHOW CREATE TRIGGER trigger_name) - 注意嵌套调用:触发器若调用了存储过程,而该过程又访问了正在迁移的表,
DISABLE不生效,得一并检查或临时改写
mysqldump 导出时触发器默认不包含
MySQL 5.7+ 版本默认启用 --skip-triggers,哪怕你没写这个参数,导出文件里也不会有 CREATE TRIGGER 语句——结果就是迁移后业务逻辑断档。
- 导出必须加
--triggers:例如mysqldump --triggers -u root -p mydb > backup.sql - 导出后立刻验证:
grep -n "CREATE TRIGGER" backup.sql,确认语句真实存在 - 别信
--all-databases自动带触发器——它照样受--skip-triggers影响
导入时常见报错及绕过方式
ERROR 1359(Trigger already exists)和 ERROR 1449(DEFINER 用户不存在)是跨库迁移高频中断点,不是语法错,而是权限和命名冲突。
- 导入前清空目标库触发器:
SELECT CONCAT('DROP TRIGGER ', TRIGGER_NAME, ';') FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA = 'mydb';,生成并执行 - 替换 DEFINER:用
sed -i "s/DEFINER=`.*`@`.*/DEFINER=CURRENT_USER/g" backup.sql,但要确保CURRENT_USER有创建权限 - MySQL 不支持
CREATE OR REPLACE TRIGGER,脚本里必须保证DROP在CREATE前执行,顺序错了就报 ERROR 1359
真正麻烦的从来不是“怎么关”,而是关完要不要开、开哪些、开了会不会因表结构拆分(如 RdRecord 从 1 张变 8 张)而直接报错——这时候留着比开着更危险。











