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

MySQL 事件調度器 完整指南:建立、管理、監控、遷移 Crontab 定時任務

     編輯:MySQL 綜合教學

MySQL 事件調度器 完整指南:建立、管理、監控、遷移 Crontab 定時任務

MySQL 5.1+ 內建 Event Scheduler,可替代 OS Crontab 執行資料庫層定時任務 (清理、統計、分區維護、備份觸發),優勢:事務一致性、無網路延遲、權限隔離、隨備份遷移。本文涵蓋啟用、語法、管理、監控、最佳實踐與遷移清單。

1. 啟用

-- 運行時啟用 (重啟失效)
SET GLOBAL event_scheduler = ON;

-- 永久生效 (my.cnf)
[mysqld]
event_scheduler = ON

-- 驗證
SHOW VARIABLES LIKE 'event_scheduler';
SELECT @@event_scheduler;

2. 建立事件語法全解

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] [ENDS timestamp]        -- 週期性

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

3. 實戰範例

-- 一次性:5 天后執行
CREATE EVENT ev_once
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 DAY
ON COMPLETION PRESERVE
DO
  INSERT INTO audit_log (msg) VALUES ('One-time cleanup executed');

-- 週期性:每天 03:00 清理 30 天前日誌
CREATE EVENT ev_daily_cleanup
ON SCHEDULE EVERY 1 DAY
  STARTS TIMESTAMP(CURDATE() + INTERVAL 1 DAY, '03:00:00')
ON COMPLETION PRESERVE
ENABLE
DO
  DELETE FROM operation_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);

-- 週期性:每月 1 號 02:00 重建統計表 (帶結束日期)
CREATE EVENT ev_monthly_stats
ON SCHEDULE EVERY 1 MONTH
  STARTS '2024-01-01 02:00:00'
  ENDS '2030-12-31 23:59:59'
ON COMPLETION PRESERVE
ENABLE
DO
  CALL sp_rebuild_monthly_stats();

4. 管理指令

-- 修改
ALTER EVENT ev_daily_cleanup
  ON SCHEDULE EVERY 1 DAY STARTS '04:00:00'
  DISABLE;  -- 暫停

-- 重命名
ALTER EVENT ev_daily_cleanup RENAME TO ev_daily_cleanup_v2;

-- 刪除
DROP EVENT IF EXISTS ev_daily_cleanup;

-- 查看定義
SHOW CREATE EVENT ev_daily_cleanup\G

-- 狀態列表
SHOW EVENTS FROM db_name\G
-- 或
SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA='db_name';\G

5. 監控與疑難排查

-- 最近執行狀態
SELECT EVENT_NAME, LAST_EXECUTED, STATUS, EXECUTE_AT
FROM information_schema.EVENTS
WHERE EVENT_SCHEMA = 'db_name';

-- 查看事件執行錯誤 (需啟用 general_log 或 slow_log)
-- 事件體內部錯誤不會自動記錄,建議在 DO 區塊包裝:
CREATE EVENT ev_safe
ON SCHEDULE EVERY 1 HOUR
DO
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE, @msg = MESSAGE_TEXT;
    INSERT INTO event_error_log (event_name, sqlstate, msg, created_at)
    VALUES ('ev_safe', @sqlstate, @msg, NOW());
    RESIGNAL;
  END;
  CALL sp_risky_operation();
END;

6. 從 Crontab 遷移清單

Crontab 任務遷移建議
mysqldump 備份保留 Crontab (需 FLUSH LOGS、檔案系統快照、跨機傳輸)
資料清理/歸檔✅ 遷移至 Event (事務保護、無 SSH 依賴)
統計報表聚合✅ 遷移至 Event (可用 CALL Procedure 封裝複雜邏輯)
分區維護 (ADD/DROP PARTITION)✅ 遷移至 Event (DDL 自動提交,注意鎖表)
外部 API 呼叫❌ 保留應用層排程 (Event 無網路能力)

7. 限制與注意

  • 事件體不能包含動態 SQL (PREPARE/EXECUTE),需封裝在 Procedure 中 CALL。
  • DISABLE 後重啟 MySQL 事件定義仍在,但 DROP 會永久刪除。
  • 事件執行權限取決於 DEFINER (預設建立者),建議明確 DEFINER = 'event_user'@'localhost' 並授予最小權限。
  • 時區:事件按 system_time_zone 執行,跨時區部署請統一 UTC。

結語:Event Scheduler 是資料庫原生的「無伺服器定時任務」。將純資料層維護工作 (清理、聚合、分區) 遷移至 Event,能簡化運維拓撲、提升執行可靠性、實現 Schema 級備份還原一致性。配合 ON COMPLETION PRESERVE、統一錯誤日誌、Grafana 監控 LAST_EXECUTED,打造自治的資料庫定時引擎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved