MySQL 5.1+ 內建事件調度器,可替代作業系統的 cron 執行資料庫內部週期性任務(清理歷史資料、統計彙總、分區維護等)。本文涵蓋啟用、語法詳解、實戰範例、權限控管與監控排錯。
-- 臨時啟用(重啟失效) SET GLOBAL event_scheduler = ON; -- 永久啟用:在 my.cnf [mysqld] 區段加入 event_scheduler = ON -- 驗證狀態 SHOW VARIABLES LIKE 'event_scheduler'; SELECT @@event_scheduler;
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 | ...}
CREATE EVENT `ev_cleanup_old_logs`
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_DATE + INTERVAL 2 HOUR
ON COMPLETION PRESERVE
ENABLE
DO
DELETE FROM `access_log` WHERE `created_at` < DATE_SUB(NOW(), INTERVAL 30 DAY);
CREATE EVENT `ev_add_monthly_partition`
ON SCHEDULE EVERY 1 MONTH
STARTS '2024-01-01 00:00:00'
ON COMPLETION PRESERVE
ENABLE
DO
CALL `sp_add_next_month_partition`();
CREATE EVENT `ev_one_time_notify`
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 MINUTE
ON COMPLETION PRESERVE
DO
INSERT INTO `notifications` (`msg`, `created_at`) VALUES ('Task started', NOW());
-- 修改事件
ALTER EVENT `ev_cleanup_old_logs`
DISABLE; -- 或 ENABLE, RENAME TO new_name, ON SCHEDULE ...
-- 刪除事件
DROP EVENT [IF EXISTS] `ev_cleanup_old_logs`;
-- 查看所有事件
SHOW EVENTS;
-- 或查詢 information_schema
SELECT * FROM information_schema.EVENTS WHERE EVENT_SCHEMA = 'mydb';
EVENT 權限才能建立/修改/刪除事件。DEFINER 權限運行(預設建立者),需確保 DEFINER 具備執行 SQL 的權限。SHOW EVENTS 中的 LAST_EXECUTED、STATUS 欄位;錯誤會寫入錯誤日誌。SHOW PROCESSLIST 中 Command = 'Daemon'、State = 'Waiting for next activation'。system_time_zone、time_zone、應用層時區一致,否則 STARTS 時間會偏移。INSERT IGNORE、DELETE WHERE 条件)。mysqldump --events 導出事件定義;遷移時注意 DEFINER 帳號是否存在。善用事件調度器,能將資料庫維護邏輯內聚於資料庫層,減少外部依賴,提升系統自治能力。