23.4.6 事件计划程序和 MySQL 特权
要启用或禁用计划事件的执行,必须设置全局event_scheduler系统变量的值。这需要足以设置全局系统变量的特权。参见第 5.1.8.1 节“系统变量特权”。
EVENT特权控制事件的创建,修改和删除。可以使用GRANT授予此特权。例如,此GRANT语句为用户jon@ghidora
授予名为myschema
的模式的EVENT特权:
GRANT EVENT ON myschema.* TO jon@ghidora;
(我们假定此用户帐户已经存在,否则我们希望它保持不变.)
要为该用户授予所有模式的EVENT特权,请使用以下语句:
GRANT EVENT ON *.* TO jon@ghidora;
EVENT特权具有全局或架构级别的范围。因此,尝试在单个 table 上授予它会导致错误,如下所示:
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());
用户 await 一分钟左右,然后执行SELECT * FROM mytable;
查询,期望在 table 中看到几个新行。而是,该 table 为空。由于用户没有该 table 的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.EVENTStabletable 明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
架构上的EVENT和INSERT特权。然后,该用户创建以下事件:
CREATE EVENT e_insert
ON SCHEDULE
EVERY 7 SECOND
DO
INSERT INTO myschema.mytable;
创建此事件后,root
撤消jon@ghidora
的EVENT特权。但是,e_insert
continue 执行,每隔 7 秒在mytable
中插入一个新行。如果root
发出了以下两个语句中的任何一个,也是如此:
-
DROP USER jon@ghidora;
-
RENAME USER jon@ghidora TO someotherguy@ghidora;
您可以通过在发出DROP USER或RENAME USER语句之前和之后检查mysql.event
table(在本节后面讨论)或INFORMATION_SCHEMA.EVENTStable(请参阅第 24.8 节““ INFORMATION_SCHEMA 事件”table”)来验证是否正确。
事件定义存储在mysql.event
table 中。要删除由另一个用户帐户创建的事件,MySQL root
用户(或具有必需特权的另一个用户)可以从该 table 中删除行。例如,要删除先前显示的事件e_insert
,root
可以使用以下语句:
DELETE FROM mysql.event
WHERE db = 'myschema'
AND name = 'e_insert';
从mysql.event
table 中删除行时,匹配事件名称和数据库架构名称非常重要。这是因为相同名称的不同事件可以存在于不同的模式中。
用户的EVENT特权存储在mysql.user
和mysql.db
table 的Event_priv
列中。在这两种情况下,此列均包含值“ Y
”或“ N
”之一。默认值为“ N
”。仅当给定用户具有全局EVENT特权(即,该特权使用GRANT EVENT ON *.*
授予)时,该用户的mysql.user.Event_priv
才设置为“ Y
”。对于架构级别的EVENT特权,GRANT在mysql.db
中创建一行,并将该行的Db
列设置为架构名称,将User
列设置为用户名称,并将Event_priv
列设置为'Y
'。绝对不需要直接操作这些 table,因为GRANT EVENT和REVOKE EVENT
语句对它们执行必需的操作。
五个状态变量提供了与事件相关的操作的计数(但不是*由事件执行的语句;请参见第 23.8 节“对存储程序的限制”)。这些是:
-
Com_create_event
:自上次服务器重新启动以来执行的CREATE EVENT条语句的数量。 -
Com_alter_event
:自上次服务器重新启动以来执行的ALTER EVENT条语句的数量。 -
Com_drop_event
:自上次服务器重新启动以来执行的DROP EVENT条语句的数量。 -
Com_show_create_event
:自上次服务器重新启动以来执行的显示创建事件条语句的数量。 -
Com_show_events
:自上次服务器重新启动以来执行的SHOW EVENTS条语句的数量。
您可以通过运行语句SHOW STATUS LIKE '%event%';
一次查看所有这些值的当前值。