首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL Event Scheduler 事件調度器完整指南:語法、啟用、定時任務實戰與注意事項

     編輯:MySQL 綜合教學

為什麼需要 Event Scheduler?

傳統依賴 Linux cron + 腳本執行定時 SQL,存在部署依賴重、多實例配置繁瑣、環境遷移易遺漏等問題。MySQL 5.1+ 內建 Event Scheduler,將調度邏輯封裝在資料庫內部,實現零外部依賴、隨備份遷移、權限統一管理。

一、核心語法詳解

CREATE [DEFINER = { user | CURRENT_USER }]
EVENT [IF NOT EXISTS] 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}

關鍵子句說明

  • ON SCHEDULE:AT 一次性執行;EVERY 週期執行。
  • STARTS / ENDS:指定週期任務的首次/結束時間。省略 STARTS 等同 STARTS CURRENT_TIMESTAMP (創建即執行首次)。
  • ON COMPLETION PRESERVE:任務結束後保留 Event 定義 (預設 NOT PRESERVE,一次性任務結束自動刪除)。
  • ENABLE/DISABLE:創建後是否立即啟用。DISABLE ON SLAVE:主庫創建同步到從庫時自動禁用,防止雙邊執行。
  • DEFINER:執行時權限檢查用戶,預設創建者。需 EVENT 權限。
  • 時區處理:調度時間基於會話 time_zone,存儲為 UTC。跨時區部署需注意。

二、啟用 Event Scheduler

動態啟用 (即時生效)

SET GLOBAL event_scheduler = ON;  -- 或 1

持久化啟用 (配置文件)

[mysqld]
event_scheduler = ON

三種狀態值

  • OFF (0):關閉,不啟動調度線程 (預設)。
  • ON (1):啟動,可動態切換。
  • DISABLED:禁用,**僅啟動時指定有效**。運行時無法從 ON/OFF 切換為 DISABLED,也無法從 DISABLED 切換出。徹底禁用調度功能。

查看狀態

SHOW PROCESSLIST; -- 可見 event_scheduler 線程
SHOW VARIABLES LIKE 'event_scheduler';

三、Event 管理操作

創建範例

-- 每小時清理會話表
CREATE EVENT e_hourly_cleanup
ON SCHEDULE EVERY 1 HOUR
COMMENT 'Clears out sessions table each hour'
DO DELETE FROM site_activity.sessions;

-- 複雜邏輯:每5秒批量寫入
DELIMITER |
CREATE EVENT e_batch_insert
ON SCHEDULE EVERY 5 SECOND
DO BEGIN
  DECLARE v INT DEFAULT 0;
  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_cleanup DISABLE; -- 暫停
ALTER EVENT e_hourly_cleanup ENABLE;  -- 恢復
ALTER EVENT e_hourly_cleanup RENAME TO e_daily_cleanup;
DROP EVENT [IF EXISTS] e_batch_insert;

查看事件

SELECT * FROM mysql.event;
SELECT * FROM information_schema.events;
SHOW EVENTS;
SHOW CREATE EVENT e_hourly_cleanup;

四、DO 子句限制與最佳實踐

  • ✅ 幾乎所有存儲過程允許的 SQL:DML、DDL、流程控制、動態 SQL (PREPARE/EXECUTE)。
  • ❌ LOCK TABLES/UNLOCK TABLES、LOAD DATA/LOAD TABLE。
  • ❌ INSERT DELAYED 不生效。
  • ❌ DO 子句中不能包含 ALTER EVENT (創建成功但執行報錯)。
  • ⚠️ 避免單純 SELECT/SHOW:結果無法返回客戶端。改用 SELECT ... INTO @var 或寫入臨時表/日志表。
  • 🔒 併發保護:若任務執行時間超過調度間隔,會並行執行多個實例。使用 GET_LOCK()、行鎖或表鎖實現單例執行。

五、實戰案例

場景:學生成績統計,每日計算前日各科平均分存入報表表

CREATE TABLE daily_score_report (
  report_date DATE PRIMARY KEY,
  subject VARCHAR(20),
  avg_score DECIMAL(5,2)
);

CREATE EVENT ev_daily_score_stat
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_DATE + INTERVAL 1 HOUR -- 每天凌晨1點
DO
  INSERT INTO daily_score_report (report_date, subject, avg_score)
  SELECT DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY), subject, AVG(score)
  FROM student_scores
  WHERE score_date = DATE_SUB(CURRENT_DATE, INTERVAL 1 DAY)
  GROUP BY subject
  ON DUPLICATE KEY UPDATE avg_score = VALUES(avg_score);

場景:動態調度存儲過程 (新增課程自動生效)

DELIMITER //
CREATE PROCEDURE sp_generate_dynamic_event()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE v_subject VARCHAR(50);
  DECLARE cur CURSOR FOR SELECT DISTINCT subject FROM student_scores;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  SET @sql = 'CREATE EVENT ev_dynamic_stat ON SCHEDULE EVERY 1 DAY DO BEGIN ';

  OPEN cur;
  read_loop: LOOP
    FETCH cur INTO v_subject;
    IF done THEN LEAVE read_loop; END IF;
    SET @sql = CONCAT(@sql, 'CALL sp_calc_subject_avg(\'', v_subject, '\'); ');
  END LOOP;
  CLOSE cur;

  SET @sql = CONCAT(@sql, 'END;');
  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
-- 定期調用此過程重建動態事件,或在課程表變更觸發器中調用

六、注意事項總結

  1. sql_mode 固化:Event 創建時的 sql_mode 將作為執行時的模式。
  2. 權限檢查:執行時以 DEFINER 權限檢查,而非調用者。
  3. 備份包含:mysqldump --events 導出事件定義,遷移無感知。
  4. 主從複制:主庫創建 Event 會同步到從庫 (若從庫 event_scheduler=ON 會執行)。建議主庫創建時指定 DISABLE ON SLAVE,由應用層控制從庫是否啟用。
  5. 替代方案:複雜業務調度建議使用專用調度平台 (Airflow, Azkaban, XXL-JOB),Event 適合資料庫內部維護類任務。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved