2

我必须每天在特定时间(比如说 00:00:00)从我的数据库中清空我的一张表。我在程序中有这个:

    CREATE DEFINER=`root`@`%` PROCEDURE `delete_day`()
    BEGIN
       TRUNCATE TABLE qmsos.module_queuemanagement_queue;
    END

我尝试制作一个每天调用并重复此事件的事件,如下所示:

CREATE 
    EVENT `delete_queue_daily`
    ON SCHEDULE EVERY 1 DAY STARTS '2017-05-12 00:00:00' 
    ON COMPLETION PRESERVE
    DO CALL delete_day();

但它不起作用。我尝试在特定时间只执行一次它并且它有效,但如果我想每天运行它就不行。

4

2 回答 2

6

我无法重现该问题。

在基本测试中,存储过程每 10 秒执行一次:

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.18    |
+-----------+
1 row in set (0.00 sec)

mysql> SET @@GLOBAL.event_scheduler = ON;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | ON    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> USE `qmsos`;
Database changed

mysql> DROP EVENT IF EXISTS `delete_queue_daily`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP PROCEDURE IF EXISTS `delete_day`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE IF EXISTS `module_queuemanagement_queue`,
    ->                      `audit_log`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `module_queuemanagement_queue` (
    ->   `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO `module_queuemanagement_queue`
    ->   (`id`)
    -> VALUES
    ->   (NULL), (NULL), (NULL), (NULL), (NULL); 
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> CREATE TABLE IF NOT EXISTS `audit_log` (
    ->   `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->   `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE EVENT `delete_queue_daily`
    ->   ON SCHEDULE EVERY 10 SECOND STARTS '2017-05-12 00:00:00' 
    ->   ON COMPLETION PRESERVE
    ->   DO CALL `delete_day`;
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER //

mysql> CREATE PROCEDURE `delete_day`()
    -> BEGIN
    ->   INSERT INTO `audit_log` (`id`) VALUES (NULL);
    ->   TRUNCATE TABLE `module_queuemanagement_queue`;
    -> END//
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;

mysql> SHOW EVENTS\G
*************************** 1. row ***************************
                  Db: qmsos
                Name: delete_queue_daily
             Definer: user@127.0.1.1
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 10
      Interval field: SECOND
              Starts: 2017-05-12 00:00:00
                Ends: NULL
              Status: ENABLED
          Originator: 0
character_set_client: utf8mb4
collation_connection: utf8mb4_general_ci
  Database Collation: utf8mb4_general_ci
1 row in set (0.00 sec)

mysql> SELECT `id`, `created_at`
    -> FROM `audit_log`;
Empty set (0.00 sec)

mysql> SELECT `id`
    -> FROM `module_queuemanagement_queue`;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+
5 rows in set (0.00 sec)

mysql> SELECT `id`, `created_at` FROM `audit_log`;
+----+---------------------+
| id | created_at          |
+----+---------------------+
|  1 | 2017-05-12 00:00:10 |
+----+---------------------+
1 row in set (0.00 sec)

mysql> SELECT `id` FROM `module_queuemanagement_queue`;
Empty set (0.00 sec)
于 2017-05-15T20:33:58.150 回答
2

您的事件定义看起来不错。请通过执行以下命令验证event_scheduler是否已启用:

SHOW VARIABLES LIKE 'event_scheduler';

如果它关闭,那么:

SET GLOBAL event_scheduler = ON;

全局 event_scheduler 系统变量确定事件调度程序是否已启用并在服务器上运行。它具有以下 3 个值之一,这些值会影响事件调度,如下所述:

  • OFF:事件调度程序已停止。事件调度程序线程未运行,未显示在 SHOW PROCESSLIST 的输出中,并且未执行任何已调度的事件。OFF 是 event_scheduler 的默认值。

    当 Event Scheduler 停止时(event_scheduler 为 OFF),可以通过将 event_scheduler 的值设置为 ON 来启动它。(见下一项。)

  • ON:启动事件调度器;事件调度程序线程运行并执行所有已调度的事件。

    当 Event Scheduler 为 ON 时,事件调度程序线程在 SHOW PROCESSLIST 的输出中列为守护进程

  • DISABLED:此值使事件调度程序无法运行。当事件调度程序被禁用时,事件调度程序线程不会运行(因此不会出现在 SHOW PROCESSLIST 的输出中)。此外,Event Scheduler 状态不能在运行时更改。

更新

要调试,请尝试简化您的表达式,并通过执行以下命令检查调度程序线程是否正在运行:

SHOW FULL PROCESSLIST;

对于即:

CREATE 
EVENT `delete_queue_daily_debug`
ON SCHEDULE EVERY 1 DAY 
STARTS TIMESTAMP(NOW() + INTERVAL 1 MINUTE) 
DO CALL delete_day();
于 2017-05-15T19:45:27.057 回答