MySQL
EVENT
(事件)
MySQL
事件是按调度表运行的任务。这些事件可称为“调度事件”。创建事件时,会将其创建为命名数据库对象,其中包含在特定时间执行或定期重复发生的
SQL
语句(或存储过程)。这在概念上与
Linux/UNIX crontab
(也称为“
cron
作业”)或
Windows
任务调度程序的理念类似。语法与相关语句如下:
CREATE EVENT event_name ON SCHEDULE schedule DO sql_statement
事件语句:
–
SET GLOBAL event_scheduler = {ON | OFF}
–
CREATE EVENT
–
ALTER EVENT
–
DROP EVENT
event_name
:事件是模式对象,与表、存储过程和触发器一样。
event_name
必须是有效的标识符,且可以按正常方式通过模式名称进行引用和
/
或限定。事件名称在模式中必须是唯一的。
schedule
:调度表是一种规则,用于指定
MySQL
执行与事件相关联的操作的时间。
sql_statement
:您必须包含按调度表执行的有效
SQL
语句或存储过程语句。此语句受到的限制与适用于存储函数和动态
SQL
的限制相同。例如,该语句无法返回结果集(如
SELECT
或
SHOW
所生成的结果集)。通常会使用
CALL
语句调用过程来执行实际操作。
1.1.
调度表
调度表是指定应在何时执行操作的规则。可以在
CREATE EVENT
和
ALTER EVENT
语句的
SCHEDULE
子句中指定调度表。
有两种类型的调度表:执行一次的调度表(使用
AT
关键字)和可重复执行的调度表(使用
EVERY
关键字)。对于后者,必须定义事件的重复频率。还可以定义一个时间段,以确定应重复执行事件的期限。
SCHEDULE
子句的语法如下所示:
AT timestamp [+ INTERVAL interval]| EVERY interval [STARTS timestamp [+ INTERVAL interval]] [ENDS timestamp [+ INTERVAL interval]]
SCHEDULE
子句可包含以下变量元素:
Ø
timestamp
:
DATETIME
或
TIMESTAMP
类型的表达式;
Ø
interval
:用于指定持续时间。持续时间的表示方法为,指定一个整数数量,后跟用于定义特定种类持续时间的关键字。有效的关键字包括:
- YEAR
- QUARTER
- MONTH
- DAY
- HOUR
- MINUTE
- WEEK
- SECOND
- YEAR_MONTH
- DAY_HOUR
- DAY_MINUTE
- DAY_SECOND
- HOUR_MINUTE
- HOUR_SECOND
- MINUTE_SECOND
事件调度程序是
mysqld
进程中的一个单独线程,负责执行调度事件。调度程序会检查是否应执行事件;如果应执行事件,则会创建新的连接来执行操作。
使用事件来自动地定期执行(维护)任务,如更新汇总表或刷新查询中的表(物化视图
仿真),或者执行夜间作业。例如,处理白天的工作、加载数据仓库或者将数据导出到
文件中。
1.2.
事件调度程序和权限
1)
事件调度程序
创建事件后,该事件将存储在数据库中,以便按调度表执行。
event_scheduler
线程会监控所有事件的调度表,在到达调度表中的时间时,该线程会启动一个新的线程来执行每个事件。
默认情况下,
event_scheduler
线程设置为
OFF
。您必须显式启用该线程,方法为修改全局
event_scheduler
服务器变量的值,将其设置为
ON
。还可以通过将服务器变量添加到选项文件中(以便更改在启动时生效)或动态使用
SET
语法来实现。如果在
event_scheduler
设置为
DISABLED
的情况下启动服务器,则无法在
MySQL
正在运行时通过
SET
语句将其启用。而必须停止
MySQL
并在启用该选项的情况下重新启动
MySQL
。
启用
event_scheduler
线程后,您可以在
SHOW PROCESSLIST
的输出(以及
INFORMATION_SCHEMA
等效项
PROCESSLIST
)中看到该线程。
可以使用
ALTER EVENT
语法更改
EVENT
。可以通过该语法更改
EVENT
的每个元素。因此,
ALTER EVENT
的语法模型几乎与
CREATE EVENT
语句的语法模型完全相同。
2)
事件调度权限
必须拥有
SUPER
权限才能设置全局
event_scheduler
变量。必须拥有
EVENT
权限才能创建、修改或删除事件。
Ø
使用
GRANT
分配权限(仅限在模式级别)
mysql> GRANT EVENT ON myschema.* TO user1@srv1;
mysql> GRANT EVENT ON *.* TO user1@srv1;
Ø
使用
REVOKE
取消事件权限
REVOKE EVENT ON myschema.* FROM user1@srv1;
要取消
EVENT
权限,请使用
REVOKE
语句。撤消用户帐户的
EVENT
权限不会删除或禁用该帐户已创建的任何事件。
用户的
EVENT
权限存储在
mysql.user
和
mysql.db
表的
Event_priv
列中。在这两种情况下,该列均存储值“
Y
”或“
N
”之一。“
N
”是默认值。仅当给定用户拥有全局
EVENT
权限时,该用户的
mysql.user.Event_priv
值才会设为“
Y
”。对于模式级别的
EVENT
权限,
GRANT
会在
mysql.db
中创建一个行,并按如下所示设置该行的列值:
l
Db
:模式的名称
l
User
:用户的名称
l
Event_priv
:“
Y
”
您不必直接操作这些表,因为
GRANT EVENT
和
REVOKE EVENT
语句会对其执行所需的操作。
1.3.
事件执行权限
事件使用事件定义者的权限进行执行。如果定义者无权执行某任务,则事件无法执行该任务。示例如下:
user1@srv1
只能为
myschema
创建
SELECT
事件:
CREATE EVENT e_store_ts ON SCHEDULE EVERY 10 SECOND
DO
INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP());
由于缺少
INSERT
权限,该事件不会在表中创建任何行。事件使用其定义者的权限进行执行,并且无法执行定义者无权执行的任何操作,了解这一点非常重要。例如,假设
user1@srv1
拥有对
myschema
的
EVENT
权限。再假设该用户拥有对
myschema
的
SELECT
权限,但是没有针对此模式的其他权限。尽管
user1@srv1
可以创建新事件,但该事件本身无法执行
INSERT
操作,因为定义者
user1@srv1
无权执行该操作。
错误日志
如果查看
MySQL
错误日志
(hostname.err)
可以看到事件正在执行,但是该事件尝试执行的操作失败(由
RetCode=0
指明):
...
060209 22:39:44 [Note] EVEX EXECUTING event newdb.e [EXPR:10]
060209 22:39:44 [Note] EVEX EXECUTED event newdb.e [EXPR:10]. RetCode=0
060209 22:39:54 [Note] EVEX EXECUTING event newdb.e [EXPR:10]
060209 22:39:54 [Note] EVEX EXECUTED event newdb.e [EXPR:10]. RetCode=0
060209 22:40:04 [Note] EVEX EXECUTING event newdb.e [EXPR:10]
060209 22:40:04 [Note] EVEX EXECUTED event newdb.e [EXPR:10]. RetCode=0
...
1.4.
检查事件
SHOW CREATE EVENT event_name
此语句显示重新创建给定事件所需的
CREATE EVENT
语句。必须提供事件名称才能查看该事件的相关信息。
SHOW EVENTS
此语句为
MySQL
扩展。它可返回事件的特征,如数据库、名称、类型、创建者以及创建和修改日期。此语句有一个优点:可基于
LIKE
模式或
WHERE
子句中提供的条件来显示特定事件。如果未提供此类条件,则
SHOW EVENTS
语句会显示所有事件的相关信息。
INFORMATION_SCHEMA.EVENTS
EVENT_CATALOG: NULL
EVENT_SCHEMA: myschema
EVENT_NAME: e_store_ts
DEFINER: user1@srv1
EVENT_BODY: SQL
EVENT_DEFINITION: INSERT INTO myschema.mytable VALUES
(UNIX_TIMESTAMP())
...
1.5.
删除事件
使用如下语法可显式删除事件:
DROP EVENT [IF EXISTS] [schema_name.]event_name;
使用
IF EXISTS
可防止因尝试删除不存在的事件而出现的错误。您必须对包含要删除的事件的数据库拥有
EVENT
权限。