傳統方案依賴系統 crontab + 腳本,存在上下文分離、權限管理分散、跨實例遷移困難、無法感知數據庫狀態等痛點。MySQL Event Scheduler (5.1+) 提供數據庫原生調度:
mysql.event 表,隨庫遷移、備份還原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 一次性 | 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 SECONDEVERY 1 WEEK ENDS '2024-12-31' |
Interval 單位:YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, 及複合如 DAY_HOUR, HOUR_MINUTE
CREATE EVENT e_log_timestamp
ON SCHEDULE EVERY 10 SECOND
DO
INSERT INTO monitor.time_log (created_at) VALUES (NOW());
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);
CREATE EVENT e_monthly_report
ON SCHEDULE EVERY 1 MONTH
STARTS '2024-02-01 03:00:00'
DO
CALL sp_generate_monthly_report();
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)。兩種策略:
event_scheduler=ON,從庫 event_scheduler=OFF。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)。兩者互補,而非互斥。