MySQL 5.7 升级到 8.0 后触发器行为变严格:默认 STRICT_TRANS_TABLES 导致赋值违规直接报错回滚;information_schema.TRIGGERS 新增字段不兼容;DEFINER 和函数 EXECUTE 权限收紧;字符集处理更敏感,需实测验证。
MySQL 5.7 升级到 8.0 后,触发器不是“语法不兼容”,而是“行为突然变严格”——同一段 BEFORE INSERT 触发器,在 5.7 可能默默修数据继续执行,在 8.0 直接报错回滚,看起来像没生效。
8.0 默认启用 STRICT_TRANS_TABLES,而 5.7 多数环境仍用宽松模式。这会让触发器里看似无害的操作直接失败:
NEW.name = NULL(但 name 是 NOT NULL):5.7 可能警告+设为默认值;8.0 直接报错,事务回滚NEW.created_at = NOW(6)(字段是 DATETIME,不支持微秒):5.7 截断后插入;8.0 拒绝赋值实操建议:
SET sql_mode = 'NO_ENGINE_SUBSTITUTION';(比全关更安全)IF NEW.col IS NULL THEN SET NEW.col = DEFAULT(col); END IF;
SELECT @@sql_mode;,别只看配置文件想用 SQL 查触发器元数据?8.0 新增了 CREATED 和 SQL_MODE 字段,5.7 执行 SELECT CREATED FROM information_schema.TRIGGERS 会报错:Unknown column 'CREATED' in field list。
实操建议:
TRIGGER_NAME、EVENT_MANIPULATION、EVENT_OBJECT_TABLE、ACTION_STATEMENT —— 这些 5.7 和 8.0 都有SELECT VERSION();,再分支处理字段列表SHOW TRIGGERS LIKE 't1' 的列顺序或数量做解析,不同版本列数可能变化5.7 中 DEFINER = 'user'@'host' 常被静默忽略或降级处理;8.0 在非 SUPER 权限下,若该用户不存在或无 TRIGGER 权限,触发器创建失败或执行时报错 Access denied。
另外,触发器内调用自定义函数时:
TRIGGER 权限,通常就能调用同库函数TRIGGER 权限,也必须额外授予该函数的 EXECUTE 权限实操建议:
DEFINER = CURRENT_USER,避免依赖隐式行为GRANT EXECUTE ON FUNCTION mydb.myfunc TO 'user'@'host';
GRANT 语句,仅 CREATE TRIGGER 不够SHOW CREATE TRIGGER 看不出问题——它输出永远“干净”,但运行时按 character_set_client 解析字符串字面量。如果客户端连的是 latin1,触发器里写的 '用户已更新' 就存成乱码字节,后续逻辑出错。
实操建议:
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci
SET NAMES utf8mb4; 或在连接串里加 ?charset=utf8mb4
SELECT ACTION_STATEMENT FROM information_schema.TRIGGERS WHERE TRIGGER_NAME = 'xxx';,直接看返回值最易被忽略的是:这些差异不靠语法检查能发现,必须在目标版本上真实跑一次插入/更新操作,观察是否报错、是否回滚、字段值是否如预期——静态检查没用。