MySQL 8.4 Reference Manual  /  ...  /  The Event Scheduler and MySQL Privileges

27.4.6 事件调度器和 MySQL 权限

要启用或禁用计划执行的事件,需要将全局event_scheduler系统变量设置为适当值。这需要具有设置全局系统变量的权限。见第7.1.9.1节,“系统变量权限”

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

GRANT EVENT ON myschema.* TO jon@ghidora;

(假设这个用户账户已经存在,我们希望它保持不变。)

要授予这个用户在所有 schema 上EVENT权限,使用以下语句:

GRANT EVENT ON *.* TO jon@ghidora;

EVENT权限具有全局或schema级别的作用。因此,尝试在单个表上授予它将导致错误,如下所示:

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@ghidoramyschemaEVENT 权限,并且对该架构有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'

查看信息架构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语句。在这个示例中,EVENT特权在myschema架构上被从jon@ghidora用户账户中移除:

REVOKE EVENT ON myschema.* FROM jon@ghidora;
Important

撤销某个用户的EVENT特权,不会删除或禁用该用户创建的事件。

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

假设用户jon@ghidora在myschema架构上拥有EVENTINSERT特权。然后,该用户创建了以下事件:

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

在创建该事件后,root撤销了jon@ghidora的EVENT特权。然而,e_insert仍然继续执行,每七秒插入一个新的行到mytable中。同样,如果root执行以下语句也是一样的:

  • DROP USER jon@ghidora;

  • RENAME USER jon@ghidora TO someotherguy@ghidora;

您可以通过检查信息架构EVENTS表,先前后执行DROP USERRENAME USER语句,验证这个结论。

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

用户的EVENT权限存储在mysql.usermysql.db表中的Event_priv列。在两个情况下,这个列都持有一个值‘Y’或‘N’。‘N’是默认值。mysql.user.Event_priv只有在该用户拥有全局EVENT权限(即使用GRANT EVENT ON *.*授予权限)时才被设置。对于schema级别的EVENT权限,GRANTmysql.db表中创建一行,并将该行的Db列设置为schema名称,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%'; 一次查看所有这些值的当前状态。