MySQL 5.1+ 內建 **Event Scheduler (事件排程器)**,可替代作業系統 crontab / Windows 排程器,直接在資料庫層執行週期性 SQL 任務。本文完整涵蓋啟用設定、語法詳解、週期/定點觸發範例、與預存程序/函數整合,打造零外部依賴的資料庫自動化作業。
-- 臨時啟用 (重啟失效)
SET GLOBAL event_scheduler = ON; -- 或 = 1
-- 永久啟用 (需修改 my.cnf/my.ini)
[mysqld]
event_scheduler = ON
驗證:SHOW VARIABLES LIKE 'event_scheduler'; → ON
CREATE EVENT event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE]
[COMMENT 'comment']
DO sql_statement;
| 需求 | ON SCHEDULE 子句 |
|---|---|
| 每分鐘執行一次 | EVERY 1 MINUTE |
| 每小時執行一次 | EVERY 1 HOUR |
| 每天固定時間 (02:58) | EVERY 1 DAY STARTS TIMESTAMP '2024-01-15 02:58:00' |
| 每週一 03:00 | EVERY 1 WEEK STARTS '2024-01-15 03:00:00' |
| 特定時間點一次性執行 | AT TIMESTAMP '2024-12-31 23:59:59' |
| 複雜間隔 (每 3 天 5 小時) | EVERY 3 DAY 5 HOUR |
CREATE EVENT evt_SyncListTest
ON SCHEDULE EVERY 1 MINUTE
DO
INSERT INTO list_test (col1, col2, col3, col4, col5)
SELECT col1, col2, col3, col4, col5 FROM table2 WHERE id = 510;
CREATE EVENT evt_DailyComplexJob
ON SCHEDULE EVERY 1 DAY
STARTS TIMESTAMP '2024-01-15 02:58:00'
DO
CALL sp_ComplexDailyJob(); -- 預先建立的預存程序
DELIMITER $$
CREATE PROCEDURE `mystock`.`TEST_KKK`()
BEGIN
DECLARE NUM INT DEFAULT 0;
DECLARE A INT;
SELECT (20 - COUNT(STOCK_CODE)) INTO NUM
FROM get_stock_list WHERE FLAG = 0 AND STIME = CURDATE();
IF NUM > 0 THEN
PREPARE STMT FROM
'INSERT INTO get_stock_list (stock_code,stock_name,close,raises,stime)
SELECT stock_code,stock_name,close,result1,selectd
FROM choice_stock
WHERE stock_code NOT IN (SELECT stock_code FROM get_stock_list WHERE stime = CURDATE() AND flag = 0)
AND selectd = CURDATE()
ORDER BY id LIMIT ?';
SET @A = NUM;
EXECUTE STMT USING @A;
DEALLOCATE PREPARE STMT;
END IF;
END$$
DELIMITER ;
DELIMITER $$
CREATE FUNCTION `FUNCTION_ADD_STOCK_FOR20`() RETURNS INT
BEGIN
DECLARE NUM, ANOTHER INT;
SELECT COUNT(STOCK_CODE) INTO NUM FROM get_stock_list WHERE FLAG = 0 AND STIME = CURDATE();
IF NUM < 20 THEN
SET ANOTHER = 20 - NUM;
INSERT INTO get_stock_list (stock_code,stock_name,close,raises,stime)
SELECT stock_code,stock_name,close,result1,selectd
FROM choice_stock
WHERE stock_code NOT IN (SELECT stock_code FROM get_stock_list WHERE stime = CURDATE() AND flag = 0)
ORDER BY id LIMIT 10;
END IF;
RETURN NUM;
END$$
DELIMITER ;
-- 查看所有事件
SHOW EVENTS;
-- 或
SELECT * FROM information_schema.EVENTS;
-- 啟用/停用特定事件
ALTER EVENT evt_SyncListTest ENABLE;
ALTER EVENT evt_SyncListTest DISABLE;
-- 刪除事件
DROP EVENT IF EXISTS evt_SyncListTest;
-- 查看事件排程器狀態與執行緒
SHOW PROCESSLIST; -- 可見 event_scheduler 執行緒
time_zone 系統變數)。
SELECT @@global.time_zone, @@session.time_zone; 為 SYSTEM 或明確時區 (如 +08:00)。STARTS TIMESTAMP 字面值**不含時區資訊**,依伺服器時區解析。| 維度 | MySQL Event | OS Crontab / Windows Task |
|---|---|---|
| 部署耦合度 | 低 (隨資料庫遷移) | 高 (需同步排程設定) |
| 權限控管 | 資料庫帳號權限 | 作業系統帳號權限 |
| 失敗重試/警報 | 需自行實作 (錯誤表 + 事件) | 內建/第三方工具豐富 |
| 長時間執行阻塞 | 佔用資料庫連線/執行緒 | 獨立進程不影響 DB |
| 版本需求 | MySQL 5.1+ | 無 |
善用 MySQL 事件排程器,將週期性資料庫作業內建化,簡化部署架構,提升運維自動化程度。