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@ghidora
对 myschema
有EVENT
权限,并且对该架构有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;
假设用户jon@ghidora在myschema架构上拥有EVENT
和INSERT
特权。然后,该用户创建了以下事件:
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 USER
或RENAME USER
语句,验证这个结论。
事件定义存储在数据字典中。要删除由其他用户账户创建的事件,您必须是 MySQL root
用户或拥有必要权限的另一个用户。
用户的EVENT
权限存储在mysql.user
和mysql.db
表中的Event_priv
列。在两个情况下,这个列都持有一个值‘Y
’或‘N
’。‘N
’是默认值。mysql.user.Event_priv
只有在该用户拥有全局EVENT
权限(即使用GRANT EVENT ON *.*
授予权限)时才被设置。对于schema级别的EVENT
权限,GRANT
在mysql.db
表中创建一行,并将该行的Db
列设置为schema名称,User
列设置为用户名称,Event_priv
列设置为‘Y
’。不需要直接操作这些表,因为GRANT EVENT
和REVOKE 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%';
一次查看所有这些值的当前状态。