Q:假设,有一个需求,希望在某一个时刻系统调用一个begin end执行一下;十分钟以后执行一下begin end。亦或有一个需求,每个多长时间周期性执行begin end。那么这个时候该怎么办呢?
A:
在Linux里面可以使用at、crontab来实现上面的需求;MySQL里面也有这样的方法,就是event对象。
也被称为MySQL事件调度器(Event Scheduler),可以在某一个时间点执行一个SQL语句或一个语句块(BEGIN … END);或者每隔固定间隔重复执行。类似于Linux下的at、crontab或Windows下的Task Scheduler。
那么如何使用event,步骤如下:
1、开启数据库的event执行调度
> 查看是否开启定时器
|
1 2 3 4 5 6 |
<span style="font-size: 16px;">mysql> show variables like <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">%event_scheduler%</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; </span>+-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | OFF | +-----------------+-------+</span> |
>开启
0:off
1:on
|
1 2 3 4 5 6 7 8 9 10 11 12 |
<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">set</span> <span style="color: rgba(0, 0, 255, 1);">global</span> event_scheduler=<span style="color: rgba(128, 0, 128, 1);">1</span><span style="color: rgba(0, 0, 0, 1);">; mysql</span>><span style="color: rgba(0, 0, 0, 1);"> exit Bye [root@studying </span>~]# mysql -uroot -<span style="color: rgba(0, 0, 0, 1);">p123 mysql</span>> show variables like <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">%event_scheduler%</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">; </span>+-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | ON | +-----------------+-------+</span> |
注意:
如果是设定事件计划为0 或OFF,即关闭事件计划进程的时候,不会有新的事件执行,但现有的正在运行的事件会执行到完毕。
对于线上环境来说,使用even时,注意在主库上开启定时器,从库上关闭定时器,event触发所有操作均会记录binlog进行主从同步,从库上开启定时器很可能造成卡库。切换主库后之后记得将新主库上的定时器打开。
2、CREATE EVENT创建
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);">CREATE [DEFINER </span>= { user |<span style="color: rgba(0, 0, 0, 1);"> CURRENT_USER }] EVENT [IF NOT EXISTS] event_name ON SCHEDULE schedule [ON COMPLETION [NOT] PRESERVE] [ENABLE </span>| DISABLE |<span style="color: rgba(0, 0, 0, 1);"> DISABLE ON SLAVE] [COMMENT </span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">comment</span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(0, 0, 0, 1);">] DO event_body; schedule: AT timestamp [</span>+<span style="color: rgba(0, 0, 0, 1);"> INTERVAL interval] ... </span> |<span style="color: rgba(0, 0, 0, 1);">EVERY interval [STARTS timestamp [</span>+<span style="color: rgba(0, 0, 0, 1);"> INTERVAL interval] ...] [ENDS timestamp [</span>+<span style="color: rgba(0, 0, 0, 1);"> INTERVAL interval] ...] interval: quantity {YEAR </span>| QUARTER | MONTH | DAY | HOUR | MINUTE |<span style="color: rgba(0, 0, 0, 1);"> WEEK </span>| SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |<span style="color: rgba(0, 0, 0, 1);"> DAY_SECOND </span>| HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}</span> |
详细解析:
①definer:指明该event的用户,服务器在执行该事件时,使用该用户来检查权限。
默认用户为当前用户,即definer = current_user;
如果明确指明了definer,则必须遵循如下规则:
1.如果没有super权限,唯一允许的值就是自己当前用户,而不能设置为其他用户。
2.如果具有super权限,则可以指定任意存在的用户;如果指定的用户不存在,则事件在执行时会报错。
②if not exists:如果事件已经存在,则不会创建,也不会报错。
③on schedule子句:指定何时执行该事件,以及如何执行该事件
1)at timestamp用于创建单次执行的事件,timestamp执行事件执行的时间(如果指定的时间是过去的时间,则会产生一个warning),时间可以是具体的时间字符串或者是一个datetime类型的表达式(如current_timestamp):
如果要指定将来某个时间,直接使用at timestamp,例:at ‘2017-08-08 08:08:08’;
如果要指定将来某个时间间隔,可利用interval关键字(interval关键字可以进行组合,at timestamp + INTERVAL 2 HOUR、 + INTERVAL 30 MINUTE)
2)every子句用于创建重复执行的事件,如果每分钟执行一次,则可以:EVERY 1 MINUTE。
当然,every子句可以指定一个开始事件和结束时间,通过STARTS和ENDS关键字来表示,具体语法与前面类似
例如:EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK。
④通常情况下,如果一个事件过期已过期,则会被立即删除。但是,create event定义中通过on completion preserve子句可以保留已过期的时间。
默认:ON COMPLETION NOT PRESERVE,也就是不保存
⑤默认情况下,enable on slave,事件一旦创建后就立即开始执行;可以通过disable关键字来禁用该事件。
⑥comment子句用于给事件添加注释。
⑦do子句用于指示事件需要执行的操作,可以是一条SQL语句,也可以是被begin…end包括的语句块,也可以在语句块中调用存储过程。
基本格式:
CREATE EVENT event_name
ON SCHEDULE <schedule>
DO <event_body>;
|
1 2 3 |
<span style="font-size: 16px;">mysql> create <span style="color: rgba(0, 0, 255, 1);">event</span><span style="color: rgba(0, 0, 0, 1);"> my_event -> on schedule every </span><span style="color: rgba(128, 0, 128, 1);">10</span><span style="color: rgba(0, 0, 0, 1);"> second </span><span style="color: rgba(0, 0, 255, 1);"><span style="color: rgba(0, 0, 0, 1);"> -></span> do</span> update myschema.mytable <span style="color: rgba(0, 0, 255, 1);">set</span> mycol = mycol + <span style="color: rgba(128, 0, 128, 1);">1</span>;</span> |
示例:建立一个计划任务,每分钟往表t2中添加数据(当前时间)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<span style="font-size: 16px;">mysql><span style="color: rgba(0, 0, 0, 1);"> show events; Empty </span><span style="color: rgba(0, 0, 255, 1);">set</span> (<span style="color: rgba(128, 0, 128, 1);">0.02</span><span style="color: rgba(0, 0, 0, 1);"> sec) mysql</span>> create table t2(id <span style="color: rgba(0, 0, 255, 1);">int</span><span style="color: rgba(0, 0, 0, 1);"> auto_increment primary key,t_time datetime); mysql</span>><span style="color: rgba(0, 0, 0, 1);"> delimiter $$ mysql</span>><span style="color: rgba(0, 0, 0, 1);"> CREATE EVENT e_daily </span>-><span style="color: rgba(0, 0, 0, 1);"> ON SCHEDULE </span>-> EVERY <span style="color: rgba(128, 0, 128, 1);">1</span><span style="color: rgba(0, 0, 0, 1);"> MINUTE </span>-> COMMENT <span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">Saves total number of sessions then clears the table each day</span><span style="color: rgba(128, 0, 0, 1);">'</span> -><span style="color: rgba(0, 0, 0, 1);"> DO </span>-><span style="color: rgba(0, 0, 0, 1);"> BEGIN </span>-> INSERT INTO t2 values (<span style="color: rgba(0, 0, 255, 1);">null</span><span style="color: rgba(0, 0, 0, 1);">,current_timestamp); </span>-><span style="color: rgba(0, 0, 0, 1);"> END $$ mysql</span>><span style="color: rgba(0, 0, 0, 1);"> delimiter ; <span style="color: rgba(255, 0, 0, 1);">……过一段时间……</span> mysql</span>> <span style="color: rgba(0, 0, 255, 1);">select</span> * <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> t2; </span>+----+---------------------+ | id | t_time | +----+---------------------+ | <span style="color: rgba(128, 0, 128, 1);">1</span> | <span style="color: rgba(128, 0, 128, 1);">2017</span>-<span style="color: rgba(128, 0, 128, 1);">04</span>-<span style="color: rgba(128, 0, 128, 1);">04</span> <span style="color: rgba(128, 0, 128, 1);">18</span>:<span style="color: rgba(128, 0, 128, 1);">02</span>:<span style="color: rgba(128, 0, 128, 1);">38</span> | | <span style="color: rgba(128, 0, 128, 1);">2</span> | <span style="color: rgba(128, 0, 128, 1);">2017</span>-<span style="color: rgba(128, 0, 128, 1);">04</span>-<span style="color: rgba(128, 0, 128, 1);">04</span> <span style="color: rgba(128, 0, 128, 1);">18</span>:<span style="color: rgba(128, 0, 128, 1);">03</span>:<span style="color: rgba(128, 0, 128, 1);">38</span> | | <span style="color: rgba(128, 0, 128, 1);">3</span> | <span style="color: rgba(128, 0, 128, 1);">2017</span>-<span style="color: rgba(128, 0, 128, 1);">04</span>-<span style="color: rgba(128, 0, 128, 1);">04</span> <span style="color: rgba(128, 0, 128, 1);">18</span>:<span style="color: rgba(128, 0, 128, 1);">04</span>:<span style="color: rgba(128, 0, 128, 1);">38</span> |<span style="color: rgba(0, 0, 0, 1);"> …………</span></span> |
3、查看新建的计划任务
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span style="font-size: 16px;">mysql> <span style="color: rgba(0, 0, 255, 1);">select</span> EVENT_NAME,LAST_EXECUTED <span style="color: rgba(0, 0, 255, 1);">from</span><span style="color: rgba(0, 0, 0, 1);"> information_schema.EVENTS; </span>+------------+---------------------+ | EVENT_NAME | LAST_EXECUTED | +------------+---------------------+ | e_daily | <span style="color: rgba(128, 0, 128, 1);">2017</span>-<span style="color: rgba(128, 0, 128, 1);">04</span>-<span style="color: rgba(128, 0, 128, 1);">04</span> <span style="color: rgba(128, 0, 128, 1);">18</span>:<span style="color: rgba(128, 0, 128, 1);">02</span>:<span style="color: rgba(128, 0, 128, 1);">38</span> | +------------+---------------------+<span style="color: rgba(0, 0, 0, 1);"> mysql</span>><span style="color: rgba(0, 0, 0, 1);"> show eventsG; </span>*************************** <span style="color: rgba(128, 0, 128, 1);">1</span>. row ***************************<span style="color: rgba(0, 0, 0, 1);"> Db: db1 Name: e_daily Definer: root@localhost Time zone: SYSTEM Type: RECURRING Execute at: NULL Interval value: </span><span style="color: rgba(128, 0, 128, 1);">1</span><span style="color: rgba(0, 0, 0, 1);"> Interval field: MINUTE Starts: </span><span style="color: rgba(128, 0, 128, 1);">2017</span>-<span style="color: rgba(128, 0, 128, 1);">04</span>-<span style="color: rgba(128, 0, 128, 1);">04</span> <span style="color: rgba(128, 0, 128, 1);">18</span>:<span style="color: rgba(128, 0, 128, 1);">02</span>:<span style="color: rgba(128, 0, 128, 1);">38</span><span style="color: rgba(0, 0, 0, 1);"> Ends: NULL Status: ENABLED Originator: </span><span style="color: rgba(128, 0, 128, 1);">0</span><span style="color: rgba(0, 0, 0, 1);"> character_set_client: utf8 collation_connection: utf8_general_ci Database Collation: latin1_swedish_ci [root@studying </span>~]# tail -<span style="color: rgba(128, 0, 128, 1);">1</span> /<span style="color: rgba(0, 0, 255, 1);">var</span>/log/<span style="color: rgba(0, 0, 0, 1);">mysqld.log </span><span style="color: rgba(128, 0, 128, 1);">2017</span>-<span style="color: rgba(128, 0, 128, 1);">04</span>-04T08:<span style="color: rgba(128, 0, 128, 1);">01</span>:<span style="color: rgba(128, 0, 128, 1);">16</span>.311514Z <span style="color: rgba(128, 0, 128, 1);">12</span> [Note] Event Scheduler: scheduler thread started with id <span style="color: rgba(128, 0, 128, 1);">12</span></span> |
通过查看MySQL日志,查看执行情况 。
4、修改alter event
|
1 2 3 4 5 6 7 8 9 |
<span style="font-size: 16px;"><span style="color: rgba(0, 0, 0, 1);">ALTER [DEFINER </span>= { user |<span style="color: rgba(0, 0, 0, 1);"> CURRENT_USER }] EVENT event_name [ON SCHEDULE schedule] [ON COMPLETION [NOT] PRESERVE] [RENAME TO new_event_name] [ENABLE </span>| DISABLE |<span style="color: rgba(0, 0, 0, 1);"> DISABLE ON SLAVE] [COMMENT </span><span style="color: rgba(128, 0, 0, 1);">'</span><span style="color: rgba(128, 0, 0, 1);">comment</span><span style="color: rgba(128, 0, 0, 1);">'</span></span><span style="color: rgba(0, 0, 0, 1);"><span style="font-size: 16px;">] [DO event_body]</span> </span> |
alter event语句可以修改事件的一个或多个属性,语法与create event语句完全相同,唯一不同的是可以对事件重命名,使用RENAME TO子句。
例如:
ALTER EVENT OLDDB.MYEVENT RENAME TO NEWDB.MYEVENT;
5、删drop event
DROP EVENT [IF EXISTS] event_name;
删除一个定义的事件。