EVENT权限是全局权限,不能限定到库或表级;它仅控制用户能否创建、修改、删除事件,事件执行时使用DEFINER权限,而非调用者权限,内部SQL能否成功取决于DEFINER是否具备对应DML权限。

EVENT权限是全局权限,不能限定到库或表级
MySQL的EVENT权限属于服务器层级权限(global privilege),它控制的是用户能否创建、修改、删除或启用/禁用事件(CREATE EVENT、DROP EVENT、ALTER EVENT等),但**不决定事件本身以谁的身份运行**。事件执行时默认使用定义者(DEFINER)的权限,而非调用者权限——这点常被误解。
所以,给用户授EVENT权限,只是允许他管理事件对象;事件内部SQL能否执行成功,取决于DEFINER账户是否具备对应数据库/表的操作权限(如SELECT、UPDATE)。
如何授予和验证EVENT权限
必须用拥有GRANT OPTION且已具备EVENT权限的账户(通常是root)执行授权:
GRANT EVENT ON *.* TO 'monitor_user'@'192.168.1.%';
注意:ON *.*不可省略或替换成ON `db_name`.*——否则会报错ERROR 1221 (HY000): Incorrect usage of DB GRANT and GLOBAL PRIVILEGES。
授权后需刷新权限:
FLUSH PRIVILEGES;
验证是否生效:
SHOW GRANTS FOR 'monitor_user'@'192.168.1.%';
输出中应包含GRANT EVENT ON *.* TO ...。也可查系统表确认:
SELECT * FROM mysql.user WHERE User = 'monitor_user' AND Host = '192.168.1.%' \G
关注字段:Event_priv: Y。
事件调度器本身必须开启,否则EVENT权限无效
EVENT权限只管“能不能建事件”,不管“事件会不会跑”。调度器开关由全局变量event_scheduler控制,它和用户权限无关:
-
OFF:所有事件暂停,即使已启用(STATUS = ENABLED)也不执行 -
ON:按计划触发事件(需同时满足:事件状态为ENABLED、当前时间在STARTS之后、未超ENDS) -
DISABLED:服务启动时强制关闭,且无法通过SET GLOBAL动态开启(需改配置文件+重启)
检查并开启(临时生效):
SELECT @@event_scheduler;
SET GLOBAL event_scheduler = ON;
若返回DISABLED,说明MySQL启动时加了--event-scheduler=DISABLED或配置文件里写了event_scheduler = DISABLED,此时必须修改my.cnf并重启。
常见权限误配导致事件静默失败
事件创建成功、调度器开着、EVENT权限也给了,但事件里的SQL却没执行——大概率是DEFINER权限不足。例如:
'app_user'@'localhost'
- 用
SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER, STATUS FROM information_schema.EVENTS;确认事件定义者 - 用
SHOW GRANTS FOR 'app_user'@'localhost';检查该定义者是否有对应操作权限 - 临时切换成定义者身份手动执行事件体SQL,看是否报错
- 避免用不存在或权限受限的账户作
DEFINER;推荐显式指定高可信账户(如'admin'@'localhost'),并确保其有最小必要权限
真正容易被忽略的点:DEFINER权限缺失不会中断事件调度流程,只会让事件体“空转”——既不报错,也不留痕迹,排查成本远高于语法错误。











