先确认event_scheduler是否启用,若为OFF或DISABLED则事件静默失败;需执行SELECT @@event_scheduler检查,临时用SET GLOBAL event_scheduler = ON开启,永久则在my.cnf的[mysqld]下添加event_scheduler = ON并重启。

事件不执行但 CREATE EVENT 没报错,先查 event_scheduler 是否真开了
很多问题根本不是权限导致的,而是调度器压根没启动。MySQL 默认关闭 event_scheduler,且 CREATE EVENT 会静默成功——它只是把语句当普通 DDL 忽略掉,不会提示你“调度器关了”。
执行这条命令确认状态:
SELECT @@event_scheduler;
返回 OFF 或 DISABLED 都不行。临时开用:
SET GLOBAL event_scheduler = ON;
永久生效要改配置文件(/etc/my.cnf 或 my.ini),在 [mysqld] 下加:
event_scheduler = ON
然后重启 MySQL。别跳过这步,否则后面所有权限检查都是白忙。
DEFINER 用户不存在或被锁,事件就静默跳过
事件以 DEFINER 身份运行,不是你当前登录用户。如果定义者账号在 mysql.user 表里查不到,或者 Account_locked = 'Y'、Password_expired = 'Y',事件会失败,错误日志里通常只写 Failed to open the event,不说明原因。
查事件定义者:
SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER, STATUS FROM information_schema.EVENTS WHERE EVENT_SCHEMA = 'your_db';
再查该用户是否存在且可用:
SELECT User, Host, Account_locked, Password_expired FROM mysql.user WHERE User = 'xxx' AND Host = 'yyy';
常见坑点:
-
localhost和127.0.0.1在权限匹配中不等价(Unix socket vs TCP),定义者写成'user'@'localhost'却从远程触发,就会失败 - 迁移后忘了导出
mysql库,mysql.user里缺定义者账号 - MySQL 8.0+ 认证插件不一致:旧库用
mysql_native_password,新库默认caching_sha2_password,导致定义者验证失败
EVENT 权限和 DEFINER 权限是两回事,缺一不可
EVENT 权限只是让你能创建/删改事件,不是让事件能跑起来。真正决定事件能否执行的是定义者账号的权限:
- 定义者必须有
EVENT权限(全局ON *.*),否则事件状态会变成SLAVESIDE_DISABLED - 定义者还必须对事件体中所有操作的对象有对应权限,比如
DELETE FROM logs就得有DELETE权限,INSERT INTO stats就得有INSERT权限 - MySQL 5.7 要给定义者授
SUPER才能指定他人作为DEFINER;MySQL 8.0.16+ 改为SYSTEM_VARIABLES_ADMIN+ROLE_ADMIN
测试方法很简单:用定义者账号连上数据库,手动执行事件体里的 SQL,看是否报错。别只信“我给了 root 权限”,root 是你登录用户,不是定义者。
查不到 last_executed 或 status 是 DISABLED,重点盯这三个字段
事件是否真在跑,不能只看 SHOW EVENTS。关键字段在 information_schema.EVENTS 里:
-
STATUS必须是ENABLED(不是DISABLED或SLAVESIDE_DISABLED) -
LAST_EXECUTED必须有值且在更新(如果一直是NULL或长时间没变,说明没执行) -
NEXT_EXECUTED应该是未来时间(如果是NULL,说明调度器没识别到这个事件)
如果发现 LAST_EXECUTED 是空的,优先检查定义者账号是否存在、是否被锁、是否有 EVENT 权限——这比翻错误日志更快。MySQL 错误日志里对这类失败记录非常模糊,基本靠排除法定位。


















