EVENT权限必须显式授予全局范围(ON .),不能限定数据库;缺少该权限会导致CREATE EVENT报错“Access denied”,且该权限不随常规权限自动赋予、不继承于角色、需直授用户。

EVENT权限必须显式授予全局范围
CREATE EVENT报错“Access denied; you need (at least one of) the SUPER privilege(s)”——不是因为没开event_scheduler,而是用户缺少EVENT权限。这个权限不会随SELECT、INSERT等常规权限自动赋予,也不在ALL PRIVILEGES里(除非显式写明)。最关键的是:GRANT EVENT ON *.* TO 'user'@'host'必须作用于全局(*.*),不能限定到某个库,比如GRANT EVENT ON `mydb`.*会直接失败。
事件执行权限取决于创建者,而非调用时机
事件以定义时的DEFINER身份执行,且权限边界在CREATE EVENT那一刻就锁死了。哪怕你后来回收了该用户的表权限,已创建的事件仍会按原权限运行。所以最小权限实践必须前置:
- 先建专用账号,如
CREATE USER 'evt_cleaner'@'localhost' IDENTIFIED BY 'p4ssw0rd!' - 只授其事件体中真实需要的DML权限,例如
GRANT DELETE ON `logs_db`.`access_log` TO 'evt_cleaner'@'localhost' - 再加
GRANT EVENT ON *.* TO 'evt_cleaner'@'localhost' - 绝对不要给
SUPER、PROCESS或REPLICATION CLIENT
MySQL 8.0+角色无法间接继承EVENT权限
即使把EVENT权限授予了某个角色,再把角色赋给用户,该用户仍无法创建事件——因为EVENT是显式权限(explicit privilege),不通过角色链传递。必须直授:GRANT EVENT ON *.* TO 'user'@'host'。若已用角色管理权限体系,需额外补这一条,且注意SET ROLE不会自动激活它。
事件到期后状态不会自动清理
ENDS时间一到,事件变成DISABLED,但记录仍留在information_schema.EVENTS里,DEFINER字段还挂着已删除用户的账号。长期运行的系统里,这类“僵尸事件”容易堆积,尤其当运维人员离职、账号被删后,SHOW EVENTS里会出现DEFINER = 'olduser'@'%'但实际无法验证的状态。定期跑SELECT EVENT_NAME, DEFINER, STATUS FROM information_schema.EVENTS WHERE STATUS = 'DISABLED'手动归档或清理,比依赖自动终止更可靠。











