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

MySQL Event Scheduler 定時任務實戰:替代系統 Crontab 的數據庫級調度方案

     編輯:MySQL 綜合教學

為什麼選擇 Event Scheduler?

傳統方案依賴系統 crontab + 腳本,存在上下文分離、權限管理分散、跨實例遷移困難、無法感知數據庫狀態等痛點。MySQL Event Scheduler (5.1+) 提供數據庫原生調度:

  • 事件定義存儲在 mysql.event 表,隨庫遷移、備份還原
  • 權限由 MySQL 權限體系統一管理 (EVENT 權限)
  • 可感知主從切換、只讀狀態、複製延遲
  • 支持精確到秒級的調度精度

啟用與狀態管理

-- 查看當前狀態
SHOW VARIABLES LIKE 'event_scheduler';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| event_scheduler | OFF   |  -- 默認關閉
+-----------------+-------+

-- 啟用 (運行時即時生效,重啟失效)
SET GLOBAL event_scheduler = ON;
-- 或
SET GLOBAL event_scheduler = 1;

-- 永久生效:修改 my.cnf
[mysqld]
event_scheduler = ON

-- 禁用 (不刪除事件定義,僅停止執行)
SET GLOBAL event_scheduler = OFF;

-- 查看 Event Scheduler 線程
SHOW PROCESSLIST;
-- 會顯示 "Daemon" 用戶,Command "Daemon", State "Waiting for next activation"

事件創建語法詳解

CREATE EVENT [IF NOT EXISTS] event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE]
[COMMENT 'comment']
DO sql_statement;

調度策略:AT (一次性) vs EVERY (周期性)

類型語法示例
AT 一次性AT timestamp [+ INTERVAL interval]AT '2024-12-31 23:59:59'
AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
EVERY 周期性EVERY interval [STARTS timestamp] [ENDS timestamp]EVERY 1 DAY STARTS '2024-01-01 02:00:00'
EVERY 10 SECOND
EVERY 1 WEEK ENDS '2024-12-31'

Interval 單位:YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, 及複合如 DAY_HOUR, HOUR_MINUTE

實戰案例庫

案例 1:每 10 秒寫入時間戳 (高頻監控)

CREATE EVENT e_log_timestamp
ON SCHEDULE EVERY 10 SECOND
DO
    INSERT INTO monitor.time_log (created_at) VALUES (NOW());

案例 2:每天凌晨 2 點清理 30 天前日誌 (標準維護)

CREATE EVENT e_cleanup_old_logs
ON SCHEDULE EVERY 1 DAY
STARTS '2024-01-01 02:00:00'
ON COMPLETION PRESERVE
ENABLE
COMMENT '清理 30 天前操作日誌'
DO
    DELETE FROM sys.operation_log WHERE created_at < DATE_SUB(NOW(), INTERVAL 30 DAY);

案例 3:每月 1 號 3 點統計月度報表 (複雜邏輯用存儲過程)

CREATE EVENT e_monthly_report
ON SCHEDULE EVERY 1 MONTH
STARTS '2024-02-01 03:00:00'
DO
    CALL sp_generate_monthly_report();

案例 4:一次性任務 - 新年歸零序列

CREATE EVENT e_reset_sequence_newyear
ON SCHEDULE AT '2025-01-01 00:00:00'
ON COMPLETION NOT PRESERVE  -- 執行後自動刪除
DO
    UPDATE config.sequences SET current_value = 0 WHERE biz_type = 'order_no';

事件管理操作

操作SQL
查看所有事件SHOW EVENTS; 或 SELECT * FROM information_schema.EVENTS;
查看特定事件詳情SHOW CREATE EVENT event_name;
修改事件 (如調整排程)ALTER EVENT event_name ON SCHEDULE EVERY 1 HOUR;
啟用/禁用事件ALTER EVENT event_name ENABLE/DISABLE;
刪除事件DROP EVENT [IF EXISTS] event_name;
查看事件執行狀態SELECT EVENT_NAME, LAST_EXECUTED, STATUS FROM information_schema.EVENTS;

權限控制

-- 授予事件權限
GRANT EVENT ON app_db.* TO 'scheduler'@'localhost';

-- 創建事件需 EVENT + 库級權限
GRANT EVENT, SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'scheduler'@'localhost';

主從複製環境下的關鍵配置

默認情況下,主庫創建的事件不會自動複製到從庫 (事件定義不寫入 Binlog)。兩種策略:

  1. 主庫啟用,從庫禁用 (推薦):
    主庫 event_scheduler=ON,從庫 event_scheduler=OFF。
    防止雙寫衝突,故障切換時手動在新主啟用。
  2. 事件定義手動同步:
    使用 mysqldump --events --no-data 導出事件定義,在從庫導入。
    需設置 log_bin_trust_function_creators=1 (若事件調用函數)。

優缺點總結與選型建議

維度Event Scheduler系統 Crontab + 腳本
部署遷移隨庫遷移,零配置需單獨部署腳本、配置 crontab
權限管理MySQL 權限體系統一OS 用戶 + 數據庫用戶雙重管理
調度精度秒級分鐘級 (標準 cron)
邏輯複雜度單條 SQL/存儲過程任意腳本語言 (Python/Shell/Go)
主從感知原生支持需腳本邏輯判斷
監控告警需自建 (查詢 information_schema)成熟工具生態 (Prometheus/Grafana)

建議:數據庫內部維護任務 (清理、統計、分區管理、序列重置) 使用 Event Scheduler;跨系統集成、文件處理、複雜業務流程 使用外部調度系統 (Airflow, Azkaban, K8s CronJob)。兩者互補,而非互斥。

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