event权限必须显式授予on .,不能限定库;事件需显式enable且调度器必须为on;执行依赖definer账户权限,缺任一层均静默失败。

EVENT 权限没显式授予,或授错了范围
MySQL 的 EVENT 权限不随 SELECT/INSERT 等常规权限自动赋予,也不包含在 ALL PRIVILEGES 里。即使你给用户授了 GRANT ALL ON app_log.*,创建事件时仍会报错 ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s)。
- 必须显式执行:
GRANT EVENT ON *.* TO 'app_user'@'localhost'—— 注意是*.*,不是某个库;MySQL 8.0+ 对通配符权限校验更严,GRANT EVENT ON app_log.*无效 - 如果只授了
EVENT ON app_log.*,CREATE EVENT 会直接拒绝,连语法检查都不过 - 云数据库(如阿里云 RDS)通常禁用
EVENT ON *.*,此时该权限根本不可用,得换外部调度
事件体里的 SQL 实际执行时,用的是 DEFINER 账户权限
事件定义里若写了 DEFINER = 'admin'@'%',那每次触发时就以 admin 身份去执行里面的 DELETE 或 INSERT。哪怕创建者是低权限用户,只要 admin 缺少对应表的 DELETE 权限,事件就静默失败——错误日志里只记 command denied,不会提示“权限不足”。
- 查当前事件的
DEFINER:SELECT db, name, definer, status FROM mysql.event WHERE db = 'app_log' - 确认该
definer用户存在且有对应 DML 权限:GRANT DELETE ON app_log.logs TO 'admin'@'%' - 未显式指定
DEFINER时,默认是CURRENT_USER,但要注意:MySQL 8.0+ 中若认证插件不匹配(比如旧库用mysql_native_password,新库默认caching_sha2_password),也会导致验证失败
event_scheduler 没真正开启,或开了但事件处于 DISABLED 状态
很多“权限不足”的报错其实是假象。比如 CREATE EVENT 成功了,但 SHOW EVENTS 显示状态是 DISABLED,last_executed 为 NULL,这时你去查日志、看权限都白忙——因为调度器压根没跑这事件。
- 先确认全局开关:
SELECT @@event_scheduler,必须返回ON(不是DISABLED或OFF) - 检查事件本身是否启用:
SELECT db, name, status FROM information_schema.EVENTS WHERE db = 'app_log',状态必须是ENABLED - 创建时漏
ENABLE是常见原因:CREATE EVENT my_clean ENABLE DO ...;否则默认是DISABLED,得手动ALTER EVENT my_clean ENABLE - 主从环境只应在主库开
event_scheduler,从库保持OFF,否则可能冲突
迁移后事件失效,常被误判为权限问题
导出时没加 --events,或没导 mysql 库,会导致 mysql.event 表内容丢失。导入后事件看似存在,但 definer 用户在新实例中不存在,或权限表没重载,结果就是事件不执行、不报错、不写日志。
- 正确导出命令:
mysqldump -u root -p --routines --triggers --events mysql > mysql_system.sql - 导入后必须执行:
FLUSH PRIVILEGES,否则权限和事件定义不会生效 - 验证
definer是否真实存在:SELECT User, Host FROM mysql.user WHERE User = 'app_user'
最容易被忽略的是:EVENT 权限只是“能建事件”,而事件能否真正执行,取决于两层权限叠加——创建者的 EVENT 权限 + DEFINER 账户对事件体内所有对象的 DML/DDL 权限。缺任何一层,都会静默失败。











