Working with MySQL Scheduled Event

摘要:在本教程中,您将了解 MySQL 事件调度程序以及如何创建事件来自动执行重复的数据库任务。

MySQL 事件是根据指定计划执行的任务。因此,有时 MySQL 事件也称为计划事件。

MySQL 事件是包含一个或多个 SQL 语句的命名对象。它们存储在数据库中并以一个或多个时间间隔执行。

例如,您可以创建一个优化数据库中所有表的事件,该事件在每周日凌晨 1:00 运行。

MySQL 事件也称为“时间触发器”,因为它们是按时间触发的,而不是像普通触发器那样由 DML 事件触发。 MySQL 事件类似于 Linux 上的 cronjob 或 Windows 上的任务调度程序。

MySQL 事件调度程序管理事件的调度和执行。

MySQL 事件在许多情况下都非常有用,例如优化数据库表、清理日志、归档数据或在非高峰时间生成复杂的报告。

MySQL 事件调度程序配置

MySQL 使用一个称为事件调度程序线程的特殊线程来执行所有已调度的事件。您可以通过执行SHOW PROCESSLIST命令来查看事件调度程序线程的状态:

SHOW PROCESSLIST;Code language: SQL (Structured Query Language) (sql)
process list

如果事件调度程序未启用,您可以设置event_scheduler系统变量来启用并启动它:

SET GLOBAL event_scheduler = ON;Code language: PHP (php)

再次执行SHOW PROCESSLIST命令查看事件调度程序线程的状态:

SHOW PROCESSLIST;
process list with event scheduler thread

要禁用并停止事件调度程序线程,请将event_scheduler系统变量设置为OFF

SET GLOBAL event_scheduler = OFF;Code language: PHP (php)

创建新的 MySQL 事件

CREATE EVENT语句创建一个新事件。以下是CREATE EVENT语句的基本语法:

CREATE EVENT [IF NOT EXIST] event_name
ON SCHEDULE schedule
DO
event_bodyCode language: SQL (Structured Query Language) (sql)

在这个语法中:

首先,使用CREATE EVENT关键字指定要创建的事件的名称。事件名称在同一数据库中必须是唯一的。

其次,在ON SCHEDULE关键字后指定计划。

如果该事件是一次性事件,请使用以下语法:

AT timestamp [+ INTERVAL]Code language: SQL (Structured Query Language) (sql)

如果事件是重复事件,请使用EVERY子句:

EVERY interval STARTS timestamp [+INTERVAL] ENDS timestamp [+INTERVAL]Code language: SQL (Structured Query Language) (sql)

第三,将 SQL 语句放在DO关键字之后。您可以在事件主体内调用存储过程。如果您有复合语句,可以将它们包装在BEGIN END块中。

MySQL CREATE EVENT示例

让我们举一些创建新事件的示例。

A) 创建一次性事件示例

以下示例创建一个将新行插入表中的准时事件。

首先,创建一个名为messages的新表:

CREATE TABLE messages (
    id INT PRIMARY KEY AUTO_INCREMENT,
    message VARCHAR(255) NOT NULL,
    created_at DATETIME NOT NULL
);Code language: SQL (Structured Query Language) (sql)

其次,使用CREATE EVENT语句创建事件:

CREATE EVENT IF NOT EXISTS test_event_01
ON SCHEDULE AT CURRENT_TIMESTAMP
DO
  INSERT INTO messages(message,created_at)
  VALUES('Test MySQL Event 1',NOW());Code language: SQL (Structured Query Language) (sql)

第三,检查messages表,您将看到一行。这意味着该事件在创建时就被执行了。

SELECT * FROM messages;Code language: SQL (Structured Query Language) (sql)
mysql 事件日志条目

要显示数据库中的所有事件,请使用以下语句:

SHOW EVENTS FROM classicmodels;Code language: SQL (Structured Query Language) (sql)
mysql 事件空列表

输出不显示任何行,因为事件在过期时会自动删除。在这种情况下,它是一次性事件,并在执行完成后过期。

要在事件过期后保留该事件,请使用ON COMPLETION PRESERVE子句。

以下语句创建另一个一次性事件,该事件在其创建时间 1 分钟后执行,并且在执行后不会删除。

CREATE EVENT test_event_02
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
ON COMPLETION PRESERVE
DO
   INSERT INTO messages(message,created_at)
   VALUES('Test MySQL Event 2',NOW());Code language: SQL (Structured Query Language) (sql)

等待1分钟,查看messages表,又添加了一条记录:

SELECT * FROM messages;Code language: SQL (Structured Query Language) (sql)
消息表记录

如果再次执行SHOW EVENTS语句,您将看到由于ON COMPLETION PRESERVE子句的作用而存在该事件:

SHOW EVENTS FROM classicmodels;Code language: SQL (Structured Query Language) (sql)
mysql 事件列表

创建重复事件示例

以下语句创建一个每分钟执行一次的重复事件,并在其创建时间后 1 小时后过期:

CREATE EVENT test_event_03
ON SCHEDULE EVERY 1 MINUTE
STARTS CURRENT_TIMESTAMP
ENDS CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
   INSERT INTO messages(message,created_at)
   VALUES('Test MySQL recurring Event',NOW());Code language: SQL (Structured Query Language) (sql)

请注意,我们使用STARTSENDS子句来定义事件的到期期限。您可以通过等待几分钟并检查messages表来测试此重复事件。

SELECT * FROM messages;Code language: SQL (Structured Query Language) (sql)
包含重复事件的消息表条目

MySQL DROP EVENT语句

要删除现有事件,请使用DROP EVENT语句,如下所示:

DROP EVENT [IF EXIST] event_name;Code language: SQL (Structured Query Language) (sql)

例如,要删除test_event_03事件,请使用以下语句:

DROP EVENT IF EXIST test_event_03;Code language: SQL (Structured Query Language) (sql)

在本教程中,您了解了 MySQL 事件以及如何从数据库创建和删除事件。

本教程有帮助吗?