首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL Event Scheduler 事件調度器完整指南:從語法到實戰

     編輯:MySQL 資料庫相關知識

Event Scheduler 核心優勢

替代 Linux Crontab 的原生定時任務方案:無外部依賴、單機多實例自動隔離、隨數據庫備份遷移、權限體系統一。適用於數據歸檔、統計聚合、緩存預熱、異步清理等場景。

調度語法詳解

CREATE EVENT event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'comment']
DO event_body;

schedule:
    AT timestamp [+ INTERVAL interval] ...           -- 單次執行
  | EVERY interval
      [STARTS timestamp [+ INTERVAL interval] ...]
      [ENDS timestamp [+ INTERVAL interval] ...]     -- 循環執行

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

單次執行示例

  • AT '2024-01-01 00:00:00' 固定時間
  • AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR 1 小時後

循環執行示例

  • EVERY 1 DAY 每天執行,創建即執行首次
  • EVERY 3 DAY STARTS '2024-01-01 00:00:00' 指定首次時間
  • EVERY 1 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 10 MINUTE ENDS '2024-12-31 23:59:59' 完整窗口控制

Event Scheduler 啟用與管理

動態啟用

SET GLOBAL event_scheduler = ON;  -- 即時生效
SELECT @@event_scheduler;          -- 驗證狀態

持久化配置

[mysqld]
event_scheduler = ON

三種狀態值

值含義動態修改
OFF / 0關閉(默認)✅ 可切換 ON
ON / 1啟用✅ 可切換 OFF
DISABLED禁用,線程不啟動❌ 僅啟動時指定,運行期不可變

事件完整生命週期管理

創建

-- 簡單 SQL
CREATE EVENT e_hourly
ON SCHEDULE EVERY 1 HOUR
COMMENT '清理過期 Session'
DO DELETE FROM sessions WHERE updated_at < NOW() - INTERVAL 1 DAY;

-- 複雜邏輯(需 DELIMITER)
DELIMITER //
CREATE EVENT e_complex
ON SCHEDULE EVERY 5 SECOND
DO
BEGIN
    DECLARE v INT DEFAULT 0;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
    WHILE v < 5 DO
        INSERT INTO t1 VALUES (0);
        UPDATE t2 SET s1 = s1 + 1;
        SET v = v + 1;
    END WHILE;
END //
DELIMITER ;

修改與刪除

ALTER EVENT e_hourly
    ON SCHEDULE EVERY 30 MINUTE
    DISABLE
    RENAME TO e_half_hour;

DROP EVENT IF EXISTS e_old;

查看元數據

SHOW EVENTS;
SHOW CREATE EVENT e_hourly;
SELECT * FROM information_schema.events WHERE event_schema = 'mydb';
SELECT * FROM mysql.event;

DO 子句限制與注意事項

  • ✅ 支持幾乎所有存儲過程允許的語句(含動態 SQL:PREPARE/EXECUTE)
  • ❌ 禁止:LOCK TABLES、LOAD DATA、INSERT DELAYED(無效)
  • ❌ 避免:純 SELECT/SHOW(結果無法獲取),改用 SELECT ... INTO
  • ❌ 禁止在 DO 中 ALTER EVENT(創建成功但執行報錯)

併發控制與時區陷阱

  • 重疊執行:若上次執行未結束,新調度仍會啟動。解決:GET_LOCK('event_name', 0) 或表鎖/行鎖互斥
  • 時區固化:創建時會話 time_zone 固化為 UTC 存儲,跨時區遷移需注意
  • SQL_MODE 繼承:創建時的 sql_mode 綁定執行期,避免隱式類型轉換差異

實戰案例:定時調用存儲過程

-- 存儲過程:每行 id2 增加 2
DROP PROCEDURE IF EXISTS sp_add_two;
DELIMITER //
CREATE PROCEDURE sp_add_two()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE v_id INT;
    DECLARE cur CURSOR FOR SELECT id FROM test;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    REPEAT
        FETCH cur INTO v_id;
        IF NOT done THEN
            UPDATE test SET id2 = id2 + 2 WHERE id = v_id;
        END IF;
    UNTIL done END REPEAT;
    CLOSE cur;
END //
DELIMITER ;

-- 事件:每天凌晨執行,持續 40 天
CREATE EVENT ev_daily_add
ON SCHEDULE EVERY 1 DAY
STARTS '2024-01-01 00:00:00'
ENDS '2024-02-10 00:00:00'
ON COMPLETION PRESERVE
DO CALL sp_add_two();
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved