mysql事件_23.4 使用事件调度

55245dff204557366d4b2e4aef2bc6b6.png

参考官方文档:

https://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html

存储例程需要mysql数据库中的 event 表。 此表是在MySQL 5.7安装过程中创建的。 如果要从早期版本升级到MySQL 5.7,请更新授权表以确保 event 表存在。

23.4.1 事件调度概述

MySQL事件是根据计划运行的任务。因此,我们有时将它们称为预定事件。创建事件时,您将创建一个命名数据库对象,其中包含一个或多个SQL语句,这些SQL语句将以一个或多个定期间隔执行,从特定日期和时间开始和结束。从概念上讲,这类似于Unix crontab(也称为“cron作业”)或Windows任务计划程序的概念。

这种类型的计划任务有时也称为“时间触发器”,暗示这些是由时间推移触发的对象。虽然这基本上是正确的,但我们更喜欢使用术语事件来避免与第23.3节“使用触发器”中讨论的类型的触发器混淆。事件应该更具体地不与“临时触发器”混淆。触发器是数据库对象,其语句是响应于在给定表上发生的特定类型的事件而执行的,((已调度的)事件是被响应于指定时间间隔而执行其语句的对象。

虽然SQL标准中没有提供事件调度的规定,但在其他数据库系统中也有先例,您可能会注意到这些实现与MySQL服务器中的实现之间存在一些相似之处。

MySQL Events具有以下主要特性和属性:

  • 在MySQL中,事件被其名称和分配给它的方案唯一标识。
  • 事件根据调度执行特定操作。 此操作由一个SQL语句组成,如果需要,它可以是BEGIN ... END块中的复合语句(请参见第13.6节“复合语句语法”)。 事件的时间可以是一次性的,或周期性的。 一次性事件仅执行一次。 周期性事件会定期重复其操作,并且可以为重复事件的计划分配特定的开始时间,结束时间。 (默认情况下,定期事件的计划在创建后立即开始,并且无限期地继续,直到它被禁用或删除。)

如果重复事件未在其调度间隔内终止,则结果可能是在一个实例中事件同时执行的多个。 如果这是不合需要的,您应该建立一个机制来防止同时发生。 例如,您可以使用GET_LOCK()函数或行或表锁定。

  • 用户可以使用sql语句来 创建,修改和删除事件。 语法无效的事件创建和修改语句失败,并显示相应的错误消息。 用户可以在事件的动作中包括需要用户实际上没有权限的语句。 事件创建或修改语句成功,但事件的操作会失败。
  • 许多属性可以使用SQL语句设置或修改。 这些属性包括事件的名称,时间,持久性(即,是否在其计划到期后保留),状态(启用或禁用),要执行的操作以及分配给它的方案。

事件的默认定义者是创建事件的用户,除非事件被更改,在这种情况下,定义者是发出影响该事件的最后一个ALTER EVENT语句的用户。 任何具有EVENT权限的用户都可以修改事件。

事件的操作语句可能包括存储例程中允许的大多数SQL语句。 对于限制

请参考 Section C.1, “Restrictions on Stored Programs”.

23.4.2 事件调度配置

事件由特殊事件调度程序线程执行; 当我们引用Event Scheduler时,我们实际上是指这个线程。 在运行时,事件调度程序线程及其当前状态可由具有SHOW PROCESSLIST输出中的PROCESS权限的用户看到,如下面的讨论所示。

全局event_scheduler系统变量确定是否在服务器上启用并运行事件调度程序。 它具有以下3个值中的一个,它们会影响事件调度,如下所述:

  • OFF:事件调度程序已停止。 事件调度程序线程未运行,未显示在SHOW PROCESSLIST的输出中,并且未被执行的任何调度事件。 OFF是event_scheduler的默认值。

当事件调度程序停止时(event_scheduler为OFF),可以通过将event_scheduler的值设置为ON来启动它。

  • ON:启动事件调度程序; 事件调度程序线程运行并执行所有计划事件。

当事件调度程序为ON时,事件调度程序线程在SHOW PROCESSLIST的输出中列为守护进程,其状态如下所示:

mysql> SHOW PROCESSLISTG

可以通过将event_scheduler的值设置为OFF来停止事件调度。

  • DISABLED:此值使事件调度程序无法运行。 当Event Scheduler为DISABLED时,事件调度程序线程不会运行(因此不会出现在SHOW PROCESSLIST的输出中)。 此外,无法在运行时更改事件计划程序状态。

如果事件调度程序状态尚未设置为DISABLED,则可以在ON和OFF之间切换event_scheduler(使用SET)。 设置此变量时,也可以使用0表示OFF,将1表示为ON。 因此,可以在mysql客户端中使用以下4个语句中的任何一个来打开事件调度程序:

SET GLOBAL event_scheduler = ON;

SET @@GLOBAL.event_scheduler = ON;

SET GLOBAL event_scheduler = 1;

SET @@GLOBAL.event_scheduler = 1;

同样,这4个语句中的任何一个都可用于关闭事件调度程序:

SET GLOBAL event_scheduler = OFF;

SET @@GLOBAL.event_scheduler = OFF;

SET GLOBAL event_scheduler = 0;

SET @@GLOBAL.event_scheduler = 0;

尽管ON和OFF具有数字等效值,但SELECT或SHOW VARIABLES为event_scheduler显示的值始终为OFF,ON或DISABLED之一。 DISABLED没有数字等价物。 因此,设置此变量时,ON和OFF通常优先于1和0。

请注意,尝试设置event_scheduler而不将其指定为全局变量会导致错误:

mysql< SET @@event_scheduler = OFF; ERROR 1229 (HY000): Variable 'event_scheduler' is a GLOBAL variable and should be set with SET GLOBAL

重要:

只有在服务器启动时才可以将事件调度程序设置为DISABLED。 如果event_scheduler为ON或OFF,则无法在运行时将其设置为DISABLED。 此外,如果事件调度程序在启动时设置为DISABLED,则无法在运行时更改event_scheduler的值。

要禁用事件调度程序,请使用以下两种方法之一:

  • 作为启动服务器时的命令行选项:

--event-scheduler=DISABLED

  • 在服务器配置文件(my.cnf或Windows系统上的my.ini)中,包括服务器将读取它的行(例如,在[mysqld]部分中):

event_scheduler=DISABLED

要启用事件计划程序,请在不使用--event-scheduler = DISABLED命令行选项的情况下,或者在删除或注释掉服务器配置文件中包含event-scheduler = DISABLED的行(如果适用)之后重新启动服务器。 或者,您可以在启动服务器时使用ON(或1)或OFF(或0)代替DISABLED值

注意

当event_scheduler设置为DISABLED时,您可以发出事件操作语句。 在这种情况下不会产生任何警告或错误(前提是这些语句本身有效)。 但是,在此变量设置为ON(或1)之前,无法执行预定事件。 一旦完成此操作,事件调度程序线程将执行满足其调度条件的所有事件。

使用--skip-grant-tables选项启动MySQL服务器会导致event_scheduler设置为DISABLED,从而覆盖命令行或my.cnf或my.ini文件中的任何其他值集(Bug#26807)。

MySQL在INFORMATION_SCHEMA数据库中提供EVENTS表。 可以查询此表以获取有关已在服务器上定义的预定事件的信息。

23.4.4 事件元数据

  • 查询mysql数据库的事件表。
  • 查询INFORMATION_SCHEMA数据库的EVENTS表。
  • 使用SHOW CREATE EVENT语句。
  • 使用SHOW EVENTS语句。

事件调度程序时间表示

MySQL中的每个会话都有一个会话时区(STZ)。 这是会话time_zone值,它在会话开始时从服务器的全局time_zone值初始化,但可以在会话期间更改。

执行CREATE EVENT或ALTER EVENT语句时当前的会话时区用于解析事件定义中指定的时间。 这成为事件时区(ETZ); 也就是说,这个是用于事件调度的时区,并且在执行时在事件中生效。

为了表示mysql.event表中的事件信息,execute_at,starts和ends次数将转换为UTC并与事件时区一起存储。 这使得事件执行能够按照定义继续执行,而不管服务器时区或夏令时效果的任何后续更改。 last_executed时间也以UTC格式存储。

如果从mysql.event中选择信息,则刚刚提到的时间将作为UTC值检索。 也可以通过从INFORMATION_SCHEMA.EVENTS表或SHOW EVENTS中选择来获得这些时间,但它们会被报告为ETZ值。 从这些来源获得的其他时间表示事件创建或最后更改的时间; 这些显示为STZ值。 下表总结了事件时间的表示。

018aeceb375c24bd203175247adec862.png

23.4.5 事件调度状态

事件调度程序将有关事件执行的信息写入MySQL服务器的错误日志,该信息以错误或警告终止。

要获取有关事件调度程序状态的信息以进行调试和故障排除,请运行mysqladmin debug; 运行此命令后,服务器的错误日志包含与事件调度程序相关的输出。

在作为事件调度程序执行的事件的一部分发生的语句中,诊断消息(不仅是错误,还包括警告)将写入错误日志,并在Windows上写入应用程序事件日志。 对于频繁执行的事件,可能会导致许多记录的消息。 例如,对于SELECT ... INTO var_list语句,如果查询未返回任何行,则会出现错误代码为1329的警告( No data),并且变量值保持不变。 如果查询返回多行,则发生错误1172( Result consisted of more than one row)。 对于任何一种情况,您都可以通过声明条件处理程序来避免记录警告; 请参见第13.6.7.2节“DECLARE ... HANDLER语法”。 对于可能检索多行的语句,另一种策略是使用LIMIT 1将结果集限制为单行。

23.4.6 事件调度和mysql 权限

要启用或禁用已调度事件的执行,必须设置全局event_scheduler系统变量的值。 这需要足以设置全局系统变量的权限。

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; 查询,期望在表中看到几个新行。 然而,该表是空的。 由于用户没有相关表的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.EVENTS表显示e_store_ts存在并已启用,但其LAST_EXECUTED列为NULL:

mysql> SELECT * FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='e_store_ts' AND EVENT_SCHEMA='myschema'G

要取消EVENT权限,请使用REVOKE语句。 在此示例中,方案myschema的EVENT权限将从jon @ ghidora用户中删除:

REVOKE EVENT ON myschema.* FROM jon@ghidora;

重要

撤消用户的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继续执行,每七秒钟在mytable中插入一个新行。 如果root发布了以下任何一个语句,情况也是如此:

  • DROP USER jon@ghidora;
  • RENAME USER jon@ghidora TO someotherguy@ghidora;

您可以通过在发出DROP USER或RENAME USER语句之前和之后检查mysql.event表(本节稍后讨论)或INFORMATION_SCHEMA.EVENTS表来验证这是否成立。

事件定义被存储在mysql.event表中。 要删除由其他用户帐户创建的事件,MySQL root用户(或具有必要权限的其他用户)可以从此表中删除行。 例如,要删除前面显示的事件e_insert,root可以使用以下语句:

DELETE FROM mysql.event WHERE db = 'myschema' AND definer = 'jon@ghidora' AND name = 'e_insert';

从mysql.event表中删除行时,匹配事件名称,数据库方案名称和用户帐户非常重要。 这是因为同一用户可以在不同的方案中创建相同名称的不同事件。

用户的EVENT权限存储在mysql.user和mysql.db表的Event_priv列中。 在这两种情况下,此列都包含值“Y”或“N”之一。 'N'是默认值。 仅当该用户具有全局EVENT权限时(即,如果使用GRANT EVENT ON *。*赋予该权限),mysql.user.Event_priv仅对给定用户设置为“Y”。 对于方案级EVENT权限,GRANT在mysql.db中创建一行,并将该行的Db列设置为方案名称,将User列设置为用户名,将Event_priv列设置为“Y”。 永远不需要直接操作这些表,因为GRANT EVENT和REVOKE EVENT语句对它们执行所需的操作。

五个状态变量提供与事件相关的操作的计数(但不包括事件执行的语句;请参见第C.1节“存储程序的限制”)。 这些是:

  • 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%';语句一次查看所有这些值的当前值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值