MySQL 5.1+ 引入 Event Scheduler (事件調度器),提供資料庫內建的定時任務能力,可替代作業系統 cron 完成數據清理、統計聚合、分區維護等周期性操作。本文詳細講解啟用方式、語法詳解、實戰範例及常見坑點。
默認關閉,三種啟用方式任選其一:
SET GLOBAL event_scheduler = ON; -- 或 1
[mysqld]
event_scheduler = ON
mysqld --event-scheduler=ON驗證狀態:
SHOW VARIABLES LIKE 'event_scheduler';
SELECT @@event_scheduler; -- ON/OFF/DISABLED
ON:運行中OFF:已停止 (可運行時開啟)DISABLED:編譯/啟動參數禁用,不可動態開啟CREATE EVENT [IF NOT EXISTS] event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE]
[COMMENT 'comment']
DO sql_statement;
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 ... | 指定具體時間點一次性執行 | 用於臨時任務 |
ON SCHEDULE EVERY ... | 週期性執行,支援複雜間隔 | 核心業務定時任務首選 |
STARTS / ENDS | 指定生效/失效時間窗口 | 避免啟動即執行或永不停止 |
ON COMPLETION PRESERVE | 任務結束後**保留**事件定義 (默認 NOT PRESERVE 即執行完自動刪除) | 生產必加,否排查困難 |
ENABLE/DISABLE | 創建即啟用/禁用 | 調試用 DISABLE,上線 ENABLE |
DO sql_statement | 執行的 SQL (可為 CALL 存儲過程) | 複雜邏輯封裝為 Procedure |
CREATE EVENT `evt_once`
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 DAY
ON COMPLETION PRESERVE ENABLE
DO UPDATE tb_test SET amount=100 WHERE id=2;
CREATE EVENT `evt_at`
ON SCHEDULE AT '2025-01-01 00:00:00'
ON COMPLETION PRESERVE ENABLE
DO CALL proc_cleanup();
CREATE EVENT `evt_daily`
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_TIMESTAMP + INTERVAL 5 DAY
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
ON COMPLETION PRESERVE ENABLE
DO DELETE FROM logs WHERE create_time < DATE_SUB(NOW(), INTERVAL 30 DAY);
CREATE EVENT `evt_monthly`
ON SCHEDULE EVERY 1 MONTH
STARTS '2025-01-01 00:00:00'
ENDS '2099-12-31 23:59:59'
ON COMPLETION PRESERVE ENABLE
DO CALL proc_monthly_stat();
ALTER EVENT event_name
[ON SCHEDULE schedule]
[RENAME TO new_event_name]
[ON COMPLETION [NOT] PRESERVE]
[COMMENT 'comment']
[ENABLE | DISABLE]
[DO sql_statement]
ALTER EVENT evt_daily DISABLE; / ENABLE;ALTER EVENT evt_daily ON SCHEDULE EVERY 1 HOUR;ALTER EVENT evt_daily RENAME TO evt_hourly;⚠️ 重大坑點:DISABLE 的事件在 MySQL 重啟後**會永久消失** (元數據表 mysql.event 中 status='DISABLED' 但在重啟時會被清理)。長期停用請用 DROP 或保留 ENABLE 但邏輯判斷跳過。
DROP EVENT [IF EXISTS] event_name;
-- 列出所有事件
SHOW EVENTS;
SELECT * FROM information_schema.EVENTS;
-- 查看特定事件創建語句
SHOW CREATE EVENT evt_daily;
-- 監控事件執行狀態 (需啟用 general_log 或 slow_log)
-- 事件執行錯誤不會中斷調度器,需自行在 SQL 中捕獲異常或查錯誤日志
EVENT 權限 (如 GRANT EVENT ON db.* TO user;)DEFINER (創建者) 權限執行,類似存儲過程 SQL SECURITY DEFINER。DO CALL proc_xxx(); 保持事件定義簡潔,便於單獨測試邏輯。ON COMPLETION PRESERVE:防止一次性/到期事件自動刪除導致審計缺失。system_time_zone、time_zone、應用層時區一致,避免 STARTS 時間偏差。SHOW PROCESSLIST 中 Command=Daemon、User=event_scheduler 為調度器主線程;工作線程顯示具體事件名。mysqldump --events 導出事件定義,避免遷移丟失。MySQL Event Scheduler 輕量、無外部依賴、權限可控,適合「數據庫內部」的周期性維護任務 (分區管理、統計表刷新、歷史數據歸檔)。對於跨系統、高可靠、複雜依賴的調度,仍建議使用專業調度平台 (Airflow、DolphinScheduler、XXL-Job)。