event_scheduler必须全局开启,否则事件不触发;需在配置文件中设event_scheduler=ON并重启,验证用SHOW VARIABLES LIKE 'event_scheduler'返回ON;时间单位须用单数MINUTE/HOUR/SECOND;存储过程需显式COMMIT;LAST_EXECUTED为空说明未执行,应查错误日志。

event_scheduler 必须全局开启,否则事件根本不触发
最常遇到的情况是:事件创建成功、状态显示 ENABLE,但 last_executed 始终为 NULL,表里数据毫无变化。根本原因就是调度器没开。
临时开启用:SET GLOBAL event_scheduler = ON;,但 MySQL 重启后会失效;生产环境必须在配置文件(my.cnf 或 my.ini)中写死:event_scheduler = ON,然后重启 mysqld。
验证是否生效:SHOW VARIABLES LIKE 'event_scheduler'; 返回值必须是 ON,不是 1 或 YES —— 这是唯一可信的判断依据。
注意两个坑:
- 如果启动时加了
--skip-grant-tables,event_scheduler强制被禁用,删掉这个参数再重启 - 普通账号默认无权修改
GLOBAL变量,需 DBA 授权SYSTEM_VARIABLES_ADMIN权限
CREATE EVENT 语法里 ON SCHEDULE 的时间单位要小心拼写
MySQL 对时间单位大小写不敏感,但单词必须完整且准确。写成 EVERY 5 MIN、EVERY 1 HOURSS 或 EVERY 30 SECONDS(复数)都会报错 ERROR 1064。
正确写法只接受单数形式:MINUTE、HOUR、SECOND、DAY 等。起始时间若用 STARTS,务必确保时间格式是 'YYYY-MM-DD HH:MM:SS',且不能早于当前时间(否则事件直接跳过,不报错也不执行)。
常见组合示例:
- 每 5 分钟执行:
EVERY 5 MINUTE - 每天凌晨 2 点:
EVERY 1 DAY STARTS '2026-09-30 02:00:00' - 从现在起每 10 秒一次(调试用):
EVERY 10 SECOND STARTS CURRENT_TIMESTAMP
存储过程里别漏写 COMMIT,尤其涉及 UPDATE/DELETE
MySQL 事件在自己的隐式事务上下文中运行。如果你的存储过程里有 UPDATE 或 DELETE,又没显式 COMMIT,在 autocommit=OFF 模式下,变更会在事件退出时自动回滚 —— 表看起来“没变”,其实是被悄悄撤回了。
解决方法很简单:在存储过程开头加 SET AUTOCOMMIT = 1;,或确保每条 DML 后跟 COMMIT;(注意不要在循环里频繁提交,影响性能)。
另一个隐藏风险:存储过程里用了 SELECT ... FOR UPDATE 或其它显式锁语句,而事件执行时间超过 innodb_lock_wait_timeout,会导致整个事件失败且不重试 —— 这种错误不会抛到客户端,只能查 mysql.general_log 或错误日志。
查看事件是否真在跑,别只信 SHOW EVENTS
SHOW EVENTS; 只显示元信息,status 是 ENABLE 不代表它正在跑。真正要看执行痕迹,得盯三个字段:
-
last_executed:最后一次成功执行的时间戳,为空说明从未跑过 -
ends和starts:注意时区!它们存的是系统时区时间,如果你设的是'2026-09-30 02:00:00',而服务器时区是 UTC+8,那实际触发就是北京时间凌晨 2 点 —— 别用本地时间去比对日志 - 最可靠的方式:
SELECT * FROM information_schema.EVENTS WHERE EVENT_NAME = 'your_event_name'\G,看LAST_EXECUTED是否在滚动更新
如果发现 LAST_EXECUTED 长期不动,优先检查存储过程内部是否有未捕获的 SQL 错误(比如字段不存在、主键冲突),这类错误会让事件中断,但不会报错给调用方。


















