Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

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

27.4.6 事件计划程序和MySQL权限

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

事件EVENT权限控制事件的创建、修改和删除。该权限可以使用GRANT授予。例如,以下GRANT语句授予用户jon@ghidora在模式myschema上的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@ghidora拥有模式myschema上的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;查询,期望看到表中的几行新数据。然而,表为空。由于用户没有模式myschema上的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语句。在这个示例中,从用户jon@ghidora的账户中撤销模式myschema上的EVENT权限:

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@ghidoraEVENT权限。然而,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 权限时才设置为 'Y'(即,如果使用 GRANT EVENT ON *.* 授予权限)。对于架构级 EVENT 权限,GRANT 创建一个 mysql.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%'; 来查看所有这些当前值。