~ MySQL 事件
MySQL Event 事件是什么
在数据库管理中,经常要周期性的执行某一命令或 SQL 语句,于是 MySQL 5.1 版本以后就提供了事件,它可以很方便的实现 MySQL 数据库的计划任务,定期运行指定命令,使用起来非常简单方便。
事件(Event)也可称为事件调度器(Event Scheduler),是用来执行定时任务的一组 SQL 集合,可以通俗理解成 MySQL 中的定时器。一个事件可调用一次,也可周期性的启动。
事件可以作为定时任务调度器,取代部分原来只能用操作系统的计划任务才能执行的工作。另外,更值得一提的是,MySQL 的事件可以实现每秒钟执行一个任务,非常适合对实时性要求较高的环境,而操作系统的计划任务只能精确到每分钟一次。
事件和触发器类似,都是在某些事情发生时启动。当数据库启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以事件也称为临时性触发器。
[1] 查看事件是否开启
在 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 的信息,则说明事件已经开启。
[2] 开启事件
开启事件主要通过以下两种方式实现。
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 中,可以通过 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
一般情况下,不建议使用不标准(以上未加粗关键字)的时间单位。
代码示例:在 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 秒插入一条数据,这说明事件创建执行成功了。
查看事件
创建好事件后,用户可以通过以下 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 中,事件创建之后,可以使用 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 语句中的子句与“创建事件”中讲解的基本相同,这里不再赘述。另外,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;
代码示例:删除事件 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)
事件,又可以称为事件调度器(Event Scheduler),是用来执行定时任务的一组 SQL 集合。简单来说,它可以很方便的实现 MySQL 数据库的计划任务,定期运行指定命令,一个事件可调用一次,也可周期性的启动。
事件和触发器类似,都是在某些事情发生时启动。当数据库启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于他们彼此相似,所以,事件也称为临时性触发器。
[ 查看事件是否开启 ] MySQL 中,查看事件是否开启:
在 MySQL 中,调度器 event_scheduler 负责调用事件一般情况下默认值为 OFF。 mysql> SHOW VARIABLES LIKE 'event_scheduler'; // 查看事件是否开启 // 或者 SELECT @@event_scheduler; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | OFF | +-----------------+-------+ mysql> SHOW PROCESSLIST; // 查看事件信息列表 +----+------+-----------------+------+---------+------+----------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------------+------+---------+------+----------+------------------+ | 2 | root | localhost:56279 | NULL | Query | 0 | starting | SHOW PROCESSLIST | +----+------+-----------------+------+---------+------+----------+------------------+
如果参数 event_scheduler 的值为 ON,或在 PROCESSLIST 中显示了 event_scheduler 的信息,则说明事件已经开启。
[ 开启事件 ] MySQL 中,开启事件主要通过以下两种方式来实现:
(1)
通过设置全局参数修改可以使用 SET GLOBAL 命令设定全局变量 event_scheduler 的值,开启或关闭事件。但是,通过 SET GLOBAL 命令开启或关闭事件,MySQL 重启服务后事件又会回到原来的状态,如果想要始终开启或关闭事件,可以修改 MySQL 配置文件。
# 将 event_scheduler 参数的值设置为 ON,表示开启事件;设置为 OFF,则关闭事件。 SET GLOBAL event_scheduler = ON ; // 设置,开启 SHOW VARIABLES LIKE 'event_scheduler'; // 查看
(2)更改配置文件
在 MySQL 配置文件中找到 [mysqld] 选项,然后在下面添加以下代码开启事件。
event_scheduler = ON // 在配置文件中添加代码并保存文件后,重启 MySQL 服务才能生效。 // 通过该方法开启或关闭事件,重启 MySQL 服务后,不会回到原来的状态。 SHOW VARIABLES LIKE 'event_scheduler';
创建事件
在 MySQL 中,可以通过 CREATE EVENT 语句来创建事件,其语法格式如下:
CREATE EVENT [IF NOT EXISTS] event_name
ON SCHEDULE 触发点 // 必选,用于定义事件执行的事件和事件间隔
[ON COMPLETION [NOT] PRESERVE] // 可选,是否循环执行
[ENABLE | DISABLE | DISABLE ON SLAVE] // 可选,默认为 enable,用于指定事件的一种属性
[COMMENT 'comment'] // 可选,用于定义注释
DO event_body; // 必选,用于指定时间启动时执行的代码;如果是多条语句,可以使用 begin-end 复合结构
# 代码示例:创建一个名称为 e_test 的事件,用于每隔 5 秒向表 tb_eventtest 中插入一条数据
# 准备工作:创建 tb_eventtest 表 create table tb_eventtest( e_id int(11) primary key auto_increment, e_user varchar(20), create_time datetime )
# 创建 e_test 事件
create event if not exists e_test on schedule every 5 second
on completion preserve
do insert into tb_eventtest(e_user,create_time) values ('MySQL',now());
创建事件后,可以查看 tb_eventtest 表中的数据;结果显示,系统每隔 5 秒插入一条数据,说明事件创建成功了。
select * from tb_eventtest
查看事件
事件创建好之后,用户可以通过以下 3 种方式来查看事件的状态信息:
- 查看 mysql.event
- 查看 information_schema.events(推荐)
- 切换到相应的数据库后执行 SHOW EVENTS
# 代码示例:查看 information_schema.events 表中的事件状态信息 SELECT * FROM information_schema.events limit 1
修改事件
在 MySQL 中,事件创建之后,可以使用 ALTER EVENT 语句修改其定义和相关属性。
ALTER EVENT event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'comment']
DO event_body;
# 代码示例 1:修改 e_test 事件,让其每隔 30 秒向表 tb_eventtest 中插入一条数据
mysql> ALTER EVENT e_test ON SCHEDULE EVERY 30 SECOND ON COMPLETION PRESERVE DO INSERT INTO tb_eventtest(user,createtime) VALUES('MySQL',NOW()); # 修改事件后,表 tb_eventtest 中的数据由原来的每 5 秒插入一条,变为每 30 秒插入一条
# 代码示例 2:使用 ALTER EVENT 语句还可以临时关闭一个已经创建的事件
# 临时关闭事件后,系统就不再继续向表 tb_eventtest 中插入数据了 ALTER EVENT e_test DISABLE; # 为了确定事件已关闭,可以查询两次(每次间隔 1 分钟)tb_eventtest 表的数据 SELECT * FROM tb_eventtest;
删除事件
在 MySQL 中,可以使用 DROP EVENT 语句删除已经创建的事件。语法格式如下:
# 基本语法 DROP EVENT [IF EXISTS] event_name; # 代码示例 drop event e_test
