目录
在数据库管理中,经常要周期性的执行某一命令或 SQL 语句,于是 MySQL 5.1 版本以后就提供了事件,它可以很方便的实现 MySQL 数据库的计划任务,定期运行指定命令,使用起来非常简单方便。
事件(Event)也可称为事件调度器(Event Scheduler),是用来执行定时任务的一组 SQL 集合,可以通俗理解成 MySQL 中的定时器。一个事件可调用一次,也可周期性的启动。
事件可以作为定时任务调度器,取代部分原来只能用操作系统的计划任务才能执行的工作。另外,更值得一提的是,MySQL 的事件可以实现每秒钟执行一个任务,非常适合对实时性要求较高的环境,而操作系统的计划任务只能精确到每分钟一次。
事件和触发器类似,都是在某些事情发生时启动。当数据库启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。
查看事件是否开启
在 MySQL 中,调度器 event_scheduler 负责调用事件。我们可以通过以下几种命令查看事件是否开启,一般情况下默认值为 OFF。SQL 命令和运行结果如下:
mysql> SHOW VARIABLES LIKE 'event_scheduler'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | OFF | +-----------------+-------+ 1 row in set, 1 warning (0.02 sec) mysql> SELECT @@event_scheduler; +-------------------+ | @@event_scheduler | +-------------------+ | OFF | +-------------------+ 1 row in set (0.00 sec) mysql> SHOW PROCESSLIST; +----+------+-----------------+------+---------+------+----------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------------+------+---------+------+----------+------------------+ | 2 | root | localhost:56279 | NULL | Query | 0 | starting | SHOW PROCESSLIST | +----+------+-----------------+------+---------+------+----------+------------------+ 1 row in set (0.01 sec)
从结果可以看出,事件没有开启。因为参数 event_scheduler 的值为 OFF,并且在 PROCESSLIST 中查看不到 event_scheduler 的信息。如果参数 event_scheduler 的值为 ON,或者在 PROCESSLIST 中显示了 event_scheduler 的信息,则说明事件已经开启。
开启事件
开启事件主要通过以下两种方式实现。
1)通过设置全局参数修改
可以使用 SET GLOBAL 命令设定全局变量 event_scheduler 的值,开启或关闭事件。将 event_scheduler 参数的值设置为 ON,表示开启事件;设置为 OFF,则关闭事件。
例如,要开启事件可以在命令行窗口中输入以下命令。
mysql> SET GLOBAL event_scheduler = ON ; Query OK, 0 rows affected (0.06 sec) mysql> SHOW VARIABLES LIKE 'event_scheduler'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | ON | +-----------------+-------+ 1 row in set, 1 warning (0.01 sec)
结果显示,event_scheduler 的值为 ON,表示事件已经开启。
通过 SET GLOBAL 命令开启或关闭事件,MySQL 重启服务后事件又会回到原来的状态,如果想要始终开启或关闭事件,可以修改 MySQL 配置文件。
2)更改配置文件
在 MySQL 配置文件中找到 [mysqld] 选项,然后在下面添加以下代码开启事件。
event_scheduler = ON
在配置文件中添加代码并保存文件后,重启 MySQL 服务才能生效。
通过该方法开启或关闭事件,重启 MySQL 服务后,不会回到原来的状态。例如,此时重启 MySQL 服务器,然后查看事件是否开启。
mysql> SHOW VARIABLES LIKE 'event_scheduler'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | ON | +-----------------+-------+ 1 row in set, 1 warning (0.01 sec)
结果显示,参数 event_scheduler 的值为 ON,表示已经开启。
MySQL如何创建并执行事件?
在 MySQL 中,可以通过 CREATE EVENT 语句来创建事件,其语法格式如下:
CREATE EVENT [IF NOT EXISTS] event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'comment']
DO event_body;
从上面的语法可以看出,CRATE EVENT 语句由多个子句组成,各子句的详细说明如下表所示。
在 ON SCHEDULE 子句中,参数 schedule 的值为一个 AT 子句,用于指定事件在某个时刻发生,其语法格式如下:
AT timestamp [+ INTERVAL interval]...
| EVERY interval
[STARTS timestamp [+ INTERVAL interval] ...]
[ENDS timestamp[+ INTERVAL interval]...]
参数说明如下:
- timestamp:一般用于只执行一次,表示一个具体的时间点,后面加上一个时间间隔,表示在这个时间间隔后事件发生。
- EVERY 子句:用于事件在指定时间区间内每隔多长时间发生一次,其中 STARTS 子句用于指定开始时间;ENDS 子句用于指定结束时间。
- interval:一般用于周期性执行,表示一个从现在开始的时间,其值由一个数值和单位构成。例如,使用“4 WEEK”表示 4 周,使用“'1:10'HOUR_MINUTE”表示 1 小时 10 分钟。间隔的长短用 DATE_ADD() 函数支配。
interval 参数可以是以下值:
YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND
一般情况下,不建议使用不标准(以上未加粗关键字)的时间单位。
例 1
在 test 数据库中创建一个名称为 e_test 的事件,用于每隔 5 秒向表 tb_eventtest 中插入一条数据。
创建 tb_eventtest 表,SQL 语句和运行结果如下:
mysql> CREATE TABLE tb_eventtest( -> id INT(11) PRIMARY KEY AUTO_INCREMENT, -> user VARCHAR(20), -> createtime DATETIME); Query OK, 0 rows affected (0.07 sec)
创建 e_test 事件,SQL 语句和运行结果如下:
mysql> CREATE EVENT IF NOT EXISTS e_test ON SCHEDULE EVERY 5 SECOND -> ON COMPLETION PRESERVE -> DO INSERT INTO tb_eventtest(user,createtime)VALUES('MySQL',NOW()); Query OK, 0 rows affected (0.04 sec)
创建事件后,查询 tb_eventtest 中的数据,SQL 语句和运行结果如下:
mysql> SELECT * FROM tb_eventtest; +----+-------+---------------------+ | id | user | createtime | +----+-------+---------------------+ | 1 | MySQL | 2020-05-21 10:41:39 | | 2 | MySQL | 2020-05-21 10:41:44 | | 3 | MySQL | 2020-05-21 10:41:49 | | 4 | MySQL | 2020-05-21 10:41:54 | +----+-------+---------------------+ 4 rows in set (0.01 sec)
从结果可以看出,系统每隔 5 秒插入一条数据,这说明事件创建执行成功了。
MySQL查看事件状态信息
创建好事件后,用户可以通过以下 3 种方式来查看事件的状态信息:
- 查看 mysql.event
- 查看 information_schema.events
- 切换到相应的数据库后执行 SHOW EVENTS;
以上方式的运行结果基本一致,这里就不一一演示了。下面查看 information_schema.events 表中的事件状态信息。SQL 语句和运行结果如下:
mysql> SELECT * FROM information_schema.events limit 1\G *************************** 1. row *************************** EVENT_CATALOG: def EVENT_SCHEMA: test EVENT_NAME: e_test DEFINER: root@localhost TIME_ZONE: SYSTEM EVENT_BODY: SQL EVENT_DEFINITION: INSERT INTO tb_eventtest(user,createtime)VALUES('MySQL',NOW()) EVENT_TYPE: RECURRING EXECUTE_AT: NULL INTERVAL_VALUE: 5 INTERVAL_FIELD: SECOND SQL_MODE: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION STARTS: 2020-05-21 10:41:39 ENDS: NULL STATUS: ENABLED ON_COMPLETION: PRESERVE CREATED: 2020-05-21 10:41:39 LAST_ALTERED: 2020-05-21 10:41:39 LAST_EXECUTED: 2020-05-21 12:38:54 EVENT_COMMENT: ORIGINATOR: 1 CHARACTER_SET_CLIENT: gbk COLLATION_CONNECTION: gbk_chinese_ci DATABASE_COLLATION: utf8_unicode_ci 1 row in set (0.08 sec)
以上参数说明如下表所示:
MySQL修改和删除事件
在 MySQL 中,事件创建之后,可以使用 ALTER EVENT 语句修改其定义和相关属性。
修改事件的语法格式如下:
ALTER EVENT event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'comment']
DO event_body;
ALTER EVENT 语句中的子句与MYSQL创建事件,一节中讲解的基本相同,这里不再赘述。另外,ALTER EVENT 语句还有一个用法就是让一个事件关闭或再次让其活动。
例 1
修改 e_test 事件,让其每隔 30 秒向表 tb_eventtest 中插入一条数据,SQL 语句和运行结果如下所示:
mysql> ALTER EVENT e_test ON SCHEDULE EVERY 30 SECOND -> ON COMPLETION PRESERVE -> DO INSERT INTO tb_eventtest(user,createtime) VALUES('MySQL',NOW()); Query OK, 0 rows affected (0.04 sec) mysql> TRUNCATE TABLE tb_eventtest; Query OK, 0 rows affected (0.04 sec) mysql> SELECT * FROM tb_eventtest; +----+-------+---------------------+ | id | user | createtime | +----+-------+---------------------+ | 1 | MySQL | 2020-05-21 13:23:49 | | 2 | MySQL | 2020-05-21 13:24:19 | +----+-------+---------------------+ 2 rows in set (0.00 sec)
由结果可以看出,修改事件后,表 tb_eventtest 中的数据由原来的每 5 秒插入一条,变为每 30 秒插入一条。
使用 ALTER EVENT 语句还可以临时关闭一个已经创建的事件。
例 2
临时关闭事件 e_test 的具体代码如下所示:
mysql> ALTER EVENT e_test DISABLE;
Query OK, 0 rows affected (0.00 sec)
查询 tb_eventtest 表中的数据,SQL 语句如下:
SELECT * FROM tb_eventtest;
为了确定事件已关闭,可以查询两次(每次间隔 1 分钟)tb_eventtest 表的数据,SQL 语句和运行结果如下所示:
mysql> TRUNCATE TABLE tb_eventtest;
Query OK, 0 rows affected (0.05 sec)
mysql> SELECT * FROM tb_eventtest;
Empty set (0.00 sec)
mysql> SELECT * FROM tb_eventtest;
Empty set (0.00 sec)
由结果可以看出,临时关闭事件后,系统就不再继续向表 tb_eventtest 中插入数据了。
删除事件
在 MySQL 中,可以使用 DROP EVENT 语句删除已经创建的事件。语法格式如下:
DROP EVENT [IF EXISTS] event_name;
例 3
删除事件 e_test,SQL 语句和运行结果如下:
mysql> DROP EVENT IF EXISTS e_test; Query OK, 0 rows affected (0.01 sec) mysql> SELECT * FROM information_schema.events \G Empty set (0.00 sec)