概述
MySQL的EVENT 是根據計劃運作的任務,類似于Linux上的crontab 任務
主要具有以下屬性
- mysql中,定時事件的對象是全局唯一的
- event根據時間表來執行操作,包含一個SQL操作,也可以使用begin,end 實作多個SQL的複合執行
- event 的權限(建立修改和删除)進行控制賦予
- 可以使用SQL語句設定或修改事件的許多屬性。這些屬性包括事件的名稱,時間,持久性(即是否在其計劃到期後保留),狀态(啟用或禁用),要執行的操作以及為其配置設定的架構
如何開啟
檢視系統變量,ON是表示已啟動,OFF表示已停止(預設值),也可以為DISABLED,表示無法運作,不推薦使用這個參數值,狀态沒法在運作是進行修改
mysql> show variables like '%event_scheduler%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| event_scheduler | ON |
+-----------------+-------+
1 row in set (0.00 sec)
隻要是開啟了這個功能,就可以在看到此子產品的線程,線程運作并執行所有定時任務
mysql> show processlist\G;
*************************** 1. row ***************************
Id: 454
User: event_scheduler
Host: localhost
db: NULL
Command: Daemon
Time: 45647
State: Waiting for next activation
Info: NULL
開啟指令,如下,關閉也是同樣
SET GLOBAL event_scheduler = ON;
SET @@GLOBAL.event_scheduler = ON;
SET GLOBAL event_scheduler = 1;
SET @@GLOBAL.event_scheduler = 1;
另外,因為event是全局變量,未指定全局來設定,會導緻報錯
mysql> set @@event_scheduler = OFF;
ERROR 1229 (HY000): Variable 'event_scheduler' is a GLOBAL variable and should be set with SET GLOBAL
權限賦予
EVENT 控制事件建立、修改和删除,權限由grant賦予,基本格式如下
mysql> GRANT EVENT ON test.* TO test;
Query OK, 0 rows affected (0.04 sec)
由于event是全局架構級别的權限,是以不能針對某個表進行賦權
mysql> GRANT EVENT ON test.test01 TO test;
ERROR 1144 (42000): Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used
很顯然的,包含在events裡面的SQL語句,定時任務執行的使用者一定需要有相關的權限,否則定時任務觸發,但是任務執行也會失敗,此時可以在mysql日志裡可以看到資訊
## 相關資訊
建立event的基本文法
CREATE EVENT
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}
系統表資訊,會記錄每個建立的定時任務
mysql> select * from information_schema.events\G;
*************************** 1. row ***************************
EVENT_CATALOG: def --永遠是def
EVENT_SCHEMA: test --所在是的資料庫名
EVENT_NAME: event_test_insert --event名
DEFINER: root@% --建立這個event的使用者
TIME_ZONE: SYSTEM --排程時區,預設是SYSTEM
EVENT_BODY: SQL --主體語言
EVENT_DEFINITION: INSERT INTO test.event_test VALUES (CURRENT_TIMESTAMP) --需要執行的部分,就是DO 的部分内容
EVENT_TYPE: RECURRING --事件重複類型,一次(TRANSIENT)重複(REPEATING)
EXECUTE_AT: NULL --如果事件的計時由EVERY子句而不是AT子句确定(也就是說,事件類型為repeating),則此列的值為NULL。
INTERVAL_VALUE: 1 --every的數字部分,對于一次性事件,此列為null
INTERVAL_FIELD: SECOND --every的機關部分,用于管理事件的時間,此處為秒
SQL_MODE: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION --在建立或更改事件并在其下執行事件時有效的SQL模式
STARTS: 2020-03-19 13:51:52 --starts子句的事件
ENDS: NULL --事件定義時包含了ENDS子句的循環事件
STATUS: DISABLED --ENABLE, DISABLE或SLAVESIDE_DISABLED 三個值之一,表示event的啟用狀态
ON_COMPLETION: PRESERVE
CREATED: 2020-03-19 13:51:52 --事件建立時間
LAST_ALTERED: 2020-03-19 13:53:10 --最後修改時間
LAST_EXECUTED: 2020-03-19 13:53:10 --最後一次執行時間
EVENT_COMMENT: --備注
ORIGINATOR: 0 --伺服器id,預設為0
CHARACTER_SET_CLIENT: utf8 --字元
COLLATION_CONNECTION: utf8_general_ci
DATABASE_COLLATION: latin1_swedish_ci
除了檢視系統表,可以有以下幾種方式來檢視已經建立的events,輸出資訊基本一緻
SHOW EVENTS;
SHOW CREATE EVENT xxxx;
SELECT * FROM MYSQL.EVENTS;
測試建立
建立一張測試表
mysql> CREATE TABLE kmtest(timeline varchar(20));
Query OK, 0 rows affected (0.02 sec)
定時循環任務
計劃每一秒插入表中目前時間,如下
mysql> CREATE EVENT event_kmtest ON SCHEDULE EVERY 1 SECOND DO INSERT INTO test.kmtest VALUES (CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)
mysql> select * from kmtest limit 2;
+---------------------+
| timeline |
+---------------------+
| 2020-03-20 14:54:07 |
| 2020-03-20 14:54:08 |
+---------------------+
2 rows in set (0.00 sec)
停止目前的定時任務
mysql> ALTER EVENT event_kmtest ON COMPLETION PRESERVE DISABLE;
Query OK, 0 rows affected (0.00 sec)
如果不再需要,可以删除任務
mysql> drop event event_kmtest;
Query OK, 0 rows affected (0.00 sec)
定某一時刻執行
建立在某一時刻執行一次任務
mysql> CREATE EVENT event_kmtest ON SCHEDULE AT '2020-03-20 15:20:20' DO set @time= CURRENT_TIMESTAMP;INSERT INTO test.kmtest VALUES (CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)
過了這個時間點再來檢視
mysql> select * from kmtest;
+---------------------+
| timeline |
+---------------------+
| 2020-03-20 15:20:20|
+---------------------+
1 row in set (0.00 sec)
在等待執行的這段時間可以看到event的執行資訊,到期執行完了就自動去除了,可以看到type是one time
mysql> show events\G;
*************************** 1. row ***************************
Db: test
Name: event_kmtest
Definer: root@%
Time zone: SYSTEM
Type: ONE TIME
多個SQL
一個events包含多個SQL,在使用的過程中,可能有時需要執行的SQL不僅僅是一個,有可能是多個,此時就需要使用定界符和begin end 來進行建立。例子如下:
delimiter |
CREATE EVENT event_kmtest ON SCHEDULE EVERY 1 SECOND
DO
begin
set @time= CURRENT_TIMESTAMP;
INSERT INTO test.kmtest VALUES (CURRENT_TIMESTAMP);
end |
delimiter;
PS:文法是沒錯的,但是我在mysql的用戶端指令行去執行時,會預設為換行輸出,我也不知道啥原因,利用一些工具來執行是沒問題的
