it技术分享just_free

it技术分享just_free

目录

查看事件是否开启

开启事件

1)通过设置全局参数修改

2)更改配置文件

MySQL如何创建并执行事件?

例 1

MySQL查看事件状态信息

MySQL修改和删除事件

例 1

例 2

删除事件

例 3


在数据库管理中,经常要周期性的执行某一命令或 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 种方式来查看事件的状态信息:

  1. 查看 mysql.event
  2. 查看 information_schema.events
  3. 切换到相应的数据库后执行 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)
11-19 08:15