创建一个事件

当你调度的大部分内容与 SQL 相关且文件相关性较低时,Mysql 具有 EVENT 功能,可以避免复杂的 cron 交互。请参见此处的手册页。将事件视为计划以重复间隔运行的存储过程。

为了节省调试与事件相关的问题的时间,请记住必须打开全局事件处理程序来处理事件。

SHOW VARIABLES WHERE variable_name='event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | OFF   |
+-----------------+-------+

关闭它,什么都不会触发。所以打开它:

SET GLOBAL event_scheduler = ON;

用于测试的模式

create table theMessages
(   id INT AUTO_INCREMENT PRIMARY KEY,
    userId INT NOT NULL,
    message VARCHAR(255) NOT NULL,
    updateDt DATETIME NOT NULL,
    KEY(updateDt)
);
 
INSERT theMessages(userId,message,updateDt) VALUES (1,'message 123','2015-08-24 11:10:09');
INSERT theMessages(userId,message,updateDt) VALUES (7,'message 124','2015-08-29');
INSERT theMessages(userId,message,updateDt) VALUES (1,'message 125','2015-09-03 12:00:00');
INSERT theMessages(userId,message,updateDt) VALUES (1,'message 126','2015-09-03 14:00:00');

提供上述插入物以显示起点。请注意,下面创建的 2 个事件将清除行。

创建 2 个活动,每天第 1 次,每 10 分钟第 2 次

忽略他们实际在做什么(互相对战)。重点在于 INTERVAL 和日程安排。

DROP EVENT IF EXISTS `delete7DayOldMessages`;
DELIMITER $$
CREATE EVENT `delete7DayOldMessages`
  ON SCHEDULE EVERY 1 DAY STARTS '2015-09-01 00:00:00'
  ON COMPLETION PRESERVE
DO BEGIN
   DELETE FROM theMessages 
   WHERE datediff(now(),updateDt)>6; -- not terribly exact, yesterday but <24hrs is still 1 day
   
  -- Other code here

END$$
DELIMITER ;

DROP EVENT IF EXISTS `Every_10_Minutes_Cleanup`;
DELIMITER $$
CREATE EVENT `Every_10_Minutes_Cleanup`
  ON SCHEDULE EVERY 10 MINUTE STARTS '2015-09-01 00:00:00'
  ON COMPLETION PRESERVE
DO BEGIN
   DELETE FROM theMessages 
   WHERE TIMESTAMPDIFF(HOUR, updateDt, now())>168; -- messages over 1 week old (168 hours)

   -- Other code here
END$$
DELIMITER ;

显示事件状态(不同方法)

SHOW EVENTS FROM my_db_name; -- List all events by schema name (db name)
SHOW EVENTS; 
SHOW EVENTS\G; -- <--------- I like this one from mysql> prompt

*************************** 1. row ***************************
                  Db: my_db_name
                Name: delete7DayOldMessages
             Definer: root@localhost
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 1
      Interval field: DAY
              Starts: 2015-09-01 00:00:00
                Ends: NULL
              Status: ENABLED
          Originator: 1
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
*************************** 2. row ***************************
                  Db: my_db_name
                Name: Every_10_Minutes_Cleanup
             Definer: root@localhost
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 10
      Interval field: MINUTE
              Starts: 2015-09-01 00:00:00
                Ends: NULL
              Status: ENABLED
          Originator: 1
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_general_ci
2 rows in set (0.06 sec)

随机的东西要考虑

DROP EVENT someEventName; - 删除事件及其代码

ON COMPLETION PRESERVE - 当事件处理完毕后,保留它。否则,它将被删除。

事件就像触发器。它们不是由用户程序调用的。相反,它们是预定的。因此,他们无声地成功或失败。

手册页的链接显示了间隔选择的相当多的灵活性,如下所示:

间隔:

quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
          WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
          DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

事件是处理系统重复和计划任务的强大机制。它们可能包含尽可能多的语句,DDL 和 DML 例程,以及你可能合理希望的复杂连接。请参阅名为 存储程序限制 的 MySQL 手册页。