MySQL 8.4 参考手册  /  ...  /  事件调度程序和 MySQL 权限

27.4.6 事件调度程序和 MySQL 权限

要启用或禁用已调度事件的执行,需要设置全局 event_scheduler 系统变量的值。这需要足够的权限来设置全局系统变量。参见 第 7.1.9.1 节,“系统变量权限”

EVENT 权限控制事件的创建、修改和删除。可以使用 GRANT 授予此权限。例如,以下 GRANT 语句为名为 myschema 的模式授予用户 jon@ghidora EVENT 权限

GRANT EVENT ON myschema.* TO jon@ghidora;

(我们假设此用户帐户已存在,并且我们希望它在其他方面保持不变。)

要授予此同一用户对所有模式的 EVENT 权限,请使用以下语句

GRANT EVENT ON *.* TO jon@ghidora;

EVENT 权限具有全局或模式级别范围。因此,尝试在单个表上授予它会导致错误,如所示

mysql> GRANT EVENT ON myschema.mytable TO jon@ghidora;
ERROR 1144 (42000): Illegal GRANT/REVOKE command; please
consult the manual to see which privileges can be used

重要的是要理解,事件以其定义者的权限执行,并且它不能执行其定义者没有相应权限的任何操作。例如,假设 jon@ghidoramyschema 具有 EVENT 权限。还假设此用户对 myschema 具有 SELECT 权限,但对该模式没有其他权限。jon@ghidora 可以创建像这样新的事件

CREATE EVENT e_store_ts
    ON SCHEDULE
      EVERY 10 SECOND
    DO
      INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP());

用户等待一分钟左右,然后执行 SELECT * FROM mytable; 查询,希望在表中看到几行新数据。但是,该表为空。由于用户没有对该表具有 INSERT 权限,因此该事件没有效果。

如果检查 MySQL 错误日志 (hostname.err),您可以看到该事件正在执行,但它尝试执行的操作失败

2013-09-24T12:41:31.261992Z 25 [ERROR] Event Scheduler:
[jon@ghidora][cookbook.e_store_ts] INSERT command denied to user
'jon'@'ghidora' for table 'mytable'
2013-09-24T12:41:31.262022Z 25 [Note] Event Scheduler:
[jon@ghidora].[myschema.e_store_ts] event execution failed.
2013-09-24T12:41:41.271796Z 26 [ERROR] Event Scheduler:
[jon@ghidora][cookbook.e_store_ts] INSERT command denied to user
'jon'@'ghidora' for table 'mytable'
2013-09-24T12:41:41.272761Z 26 [Note] Event Scheduler:
[jon@ghidora].[myschema.e_store_ts] event execution failed.

由于此用户很可能无法访问错误日志,因此可以通过直接执行该事件的操作语句来验证该语句是否有效

mysql> INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP());
ERROR 1142 (42000): INSERT command denied to user
'jon'@'ghidora' for table 'mytable'

检查 Information Schema EVENTS 表显示 e_store_ts 存在并且已启用,但其 LAST_EXECUTED 列为 NULL

mysql> SELECT * FROM INFORMATION_SCHEMA.EVENTS
     >     WHERE EVENT_NAME='e_store_ts'
     >     AND EVENT_SCHEMA='myschema'\G
*************************** 1. row ***************************
   EVENT_CATALOG: NULL
    EVENT_SCHEMA: myschema
      EVENT_NAME: e_store_ts
         DEFINER: jon@ghidora
      EVENT_BODY: SQL
EVENT_DEFINITION: INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP())
      EVENT_TYPE: RECURRING
      EXECUTE_AT: NULL
  INTERVAL_VALUE: 5
  INTERVAL_FIELD: SECOND
        SQL_MODE: NULL
          STARTS: 0000-00-00 00:00:00
            ENDS: 0000-00-00 00:00:00
          STATUS: ENABLED
   ON_COMPLETION: NOT PRESERVE
         CREATED: 2006-02-09 22:36:06
    LAST_ALTERED: 2006-02-09 22:36:06
   LAST_EXECUTED: NULL
   EVENT_COMMENT:
1 row in set (0.00 sec)

要撤销 EVENT 权限,请使用 REVOKE 语句。在此示例中,从 jon@ghidora 用户帐户中删除了对模式 myschemaEVENT 权限

REVOKE EVENT ON myschema.* FROM jon@ghidora;
重要

从用户撤销 EVENT 权限不会删除或禁用该用户可能创建的任何事件。

重命名或删除创建事件的用户不会导致事件迁移或删除。

假设用户 jon@ghidora 已被授予对 myschema 模式具有 EVENTINSERT 权限。然后,此用户创建以下事件

CREATE EVENT e_insert
    ON SCHEDULE
      EVERY 7 SECOND
    DO
      INSERT INTO myschema.mytable;

创建此事件后,root 撤销了 jon@ghidoraEVENT 权限。但是,e_insert 继续执行,每 7 秒在 mytable 中插入一行新数据。如果 root 已经发出以下两个语句中的任何一个,结果也是一样

  • DROP USER jon@ghidora;

  • RENAME USER jon@ghidora TO someotherguy@ghidora;

可以通过在发出 DROP USERRENAME USER 语句之前和之后检查 Information Schema EVENTS 表来验证这一点。

事件定义存储在数据字典中。要删除由另一个用户帐户创建的事件,您必须是 MySQL root 用户或具有必要权限的其他用户。

用户的 EVENT 权限存储在 mysql.usermysql.db 表的 Event_priv 列中。在这两种情况下,此列都包含值 'Y' 或 'N' 之一。'N' 是默认值。仅当给定用户具有全局 EVENT 权限时(即,如果权限是使用 GRANT EVENT ON *.* 授予的),mysql.user.Event_priv 才会被设置为 'Y'。对于模式级别 EVENT 权限,GRANTmysql.db 中创建一个行,并将该行的 Db 列设置为模式的名称,将 User 列设置为用户的名称,并将 Event_priv 列设置为 'Y'。永远不应该直接操作这些表,因为 GRANT EVENTREVOKE EVENT 语句会在它们上执行必需的操作。

五个状态变量提供与事件相关的操作计数(但提供事件执行的语句计数;参见 第 27.8 节,“存储程序限制”)。它们是

  • Com_create_event:自上次服务器重启以来执行的 CREATE EVENT 语句数量。

  • Com_alter_event:自上次服务器重启以来执行的 ALTER EVENT 语句数量。

  • Com_drop_event:自上次服务器重启以来执行的 DROP EVENT 语句数量。

  • Com_show_create_event:自上次服务器重启以来执行的 SHOW CREATE EVENT 语句数量。

  • Com_show_events:自上次服务器重启以来执行的 SHOW EVENTS 语句数量。

您可以通过运行语句 SHOW STATUS LIKE '%event%'; 来一次查看所有这些语句的当前值。