注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

isblog主页

或许不一定要做得最多,但一定要做得最好! 能力就是一种财富,积累越多,就越体现你

 
 
 

日志

 
 

MySQL事件调度器(Event Scheduler)介绍  

2011-12-06 09:10:00|  分类: MySql |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、前言

  自MySQL5.1.6起,增加了一个非常有特色的功能–事件调度器(Event Scheduler),可以用做定时执行某些特定任务(例如:删除记录、对数据进行汇总等等),来取代原先只能由操作系统的计划任务来执行的工作。更值得一提的是MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。对于一些对数据实时性要求比较高的应用(例如:股票、赔率、比分等)就非常适合。

  事件调度器有时也可称为临时触发器(temporal triggers),因为事件调度器是基于特定时间周期触发来执行某些任务,而触发器(Triggers)是基于某个表所产生的事件触发的,区别也就在这里。

  在使用这个功能之前必须确保event_scheduler已开启,可执行

SET GLOBAL event_scheduler = 1;

  或

SET GLOBAL event_scheduler = ON;

好了,上面虽然启动了 EVENT ,但是每次重启 mysql 之后 EVENT 并没有自动启动,那么如何让它自动启动呢?

方法一:找到当前使用的 .cnf 文件,在 [mysqld] 的下面加入如下行

event_scheduler=1

方法二:启动 mysql 的时候增加 --event_scheduler=1

mysql start --event_scheduler=1

  要查看当前是否已开启事件调度器,可执行如下SQL:

SHOW VARIABLES LIKE 'event_scheduler';

  或

SELECT @@event_scheduler;

  或

SHOW PROCESSLIST;

  二、创建事件(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}
语法说明: CREATE EVENT
[IF NOT EXISTS] /* 标注 1 */
event_name /* 标注 2 */
ON SCHEDULE schedule /* 标注3 */
[ON COMPLETION [NOT] PRESERVE] /* 标注4 */
[ENABLE | DISABLE] /* 标注5 */
[COMMENT 'comment'] /* 标注6 */
DO sql_statement /* 标注7 */
标注 1: [IF NOT EXISTS]
你可以在其他的CREATE 语法钟找到类似的语法,这个句子的意思是:如果这
个对象已经存在那么就不管它,如果没有就创建一个。
标注 2: event_name /*事件名称*/
名称最大长度可以是64个字节,可以通过单引号限定(如果你运行在ANSI模
式下是双引号)。名字必须是当前Schema(Database)中唯一的,同一个
数据库或Schema中不能有同名的事件,这是必须的,现在的MySQL Manual
中关于这个的定义可能有错。
提示: 为了避免命名规范带来的不便,最好让事件名称具有描述整个事件的能
力。例如`E1`这个名字就没有清晰描述事件的能力,而`MONTH_END`这个名字
Always Benny&Viva
仅当是周期(月末)运行的时候才具有描述性,但如果你需要每天运行这个事件
就没有意义了。
用例:
MONTH_END
`Background Check`
标注 3: ON SCHEDULE 计划任务
有两种设定计划任务的方式:
AT 时戳
/* "单次的计划任务" */
EVERY 时间(单位)的数量 时间单位 [STARTS 时戳] [ENDS时戳]
/* "重复的计划任务" */
在两种计划任务中,时戳可以是任意的TIMESTAMP 和DATETIME 数据类型,要
求提供的是将来的时间(大于CURRENT_TIMESTAMP),而且小于Unix时间的
最后时间(等于或小于'2037-12-31 23:59:59')。
用例:
TIMESTAMP '2020-01-01 00:00:00' - INTERVAL '3' DAY
CURRENT_TIMESTAMP
timestampadd(YEAR,1,'2020-01-01 00:00:00')
20070707121212
'2007-01-01 23:59:59'
在重复的计划任务中,时间(单位)的数量可以是任意非空(Not Null)的整数
式,时间单位是关键词:YEAR,MONTH,DAY,HOUR,MINUTE 或者SECOND。
提示: 其他的时间单位也是合法的如:QUARTER, WEEK, YEAR_MONTH,
DAY_HOUR, DAY_MINUTE, DAY_SECOND, HOUR_MINUTE,
HOUR_SECOND, MINUTE_SECOND,但他们是非标准不实用也不需要的。
实际上单次的计划任务只是重复的计划任务的一个即时停止的特殊例子。下面这
两个语句虽然在技术上不一样,但实现的效果是一样的:
CREATE EVENT Transient
ON SCHEDULE AT NOW()
DO SET @a=@a;
CREATE EVENT Recurring
ON SCHEDULE EVERY 1 YEAR STARTS NOW() ENDS NOW()
Always Benny&Viva
DO SET @a=@a;
标注 4: [ON COMPLETION [NOT] PRESERVE]
这里COMPLETION的意思是"当这个事件不会再发生的时候",即当单次计划任
务执行完毕后或当重复性的计划任务执行到了ENDS阶段。而声明PRESERVE
的作用是使事件在执行完毕后不会被Drop掉。
提示: 基本不需要试用这个语句。
标注 5: [ENABLE | DISABLE]
在这里设定事件的状态,可选参数为Enable和Disable,如果是Enable 的话,
那么系统就会尝试执行这个事件。有些特殊的时候你可能需要关闭事件特性,你
可以试用下面命令关闭或开启事件:"ALTER EVENT ... ENABLE" or "ALTER
EVENT ... DISABLE".
标注 6: [COMMENT 'comment']
注释会出现在元数据中,它存储在information_schema表的COMMENT列,
最大长度为64个字节。
下面添加注释的方式是不对的:
CREATE EVENT Wrong ON SCHEDULE EVERY 1 DAY
DO /* Daily report for lower management */ CALL report157();
因为行内部的注释会被MySQL的解析器分离,不会被用户看见。所以我们要用
下面的方式来添加注释:
CREATE EVENT Right ON SCHEDULE EVERY 1 DAY
COMMENT 'Daily report for lower management'
DO CALL report157();
提示: 当然最好是事件名字自身就能说明用途,那么就不需要注释了。
标注 7: DO sql_statement /*SQL 语句*/
每当事件被执行的时候,系统就会执行这个部分的SQL语句。
这里的SQL语句可以是复合语句,例如:
BEGIN DROP TABLE test.t1;
DROP TABLE test.t2;
END
如果你在客户端使用复合语句,记得要使用分隔符。

  1) 首先来看一个简单的例子来演示每秒插入一条记录到数据表

USE test; CREATE TABLE aaa (timeline TIMESTAMP); CREATE EVENT e_test_insert   ON SCHEDULE EVERY 1 SECOND   DO INSERT INTO test.aaa VALUES (CURRENT_TIMESTAMP);

  等待3秒钟后,再执行查询看看:

mysql> SELECT * FROM aaa; +---------------------+ | timeline      | +---------------------+ | 2007-07-18 20:44:26 | | 2007-07-18 20:44:27 | | 2007-07-18 20:44:28 | +---------------------+

  2) 5天后清空test表:

CREATE EVENT e_test   ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 DAY   DO TRUNCATE TABLE test.aaa;

  3) 2007年7月20日12点整清空test表:

CREATE EVENT e_test   ON SCHEDULE AT TIMESTAMP '2007-07-20 12:00:00'   DO TRUNCATE TABLE test.aaa;

  4) 每天定时清空test表:

CREATE EVENT e_test   ON SCHEDULE EVERY 1 DAY   DO TRUNCATE TABLE test.aaa;

  5) 5天后开启每天定时清空test表:

CREATE EVENT e_test   ON SCHEDULE EVERY 1 DAY   STARTS CURRENT_TIMESTAMP + INTERVAL 5 DAY   DO TRUNCATE TABLE test.aaa;

  6) 每天定时清空test表,5天后停止执行:

CREATE EVENT e_test   ON SCHEDULE EVERY 1 DAY   ENDS CURRENT_TIMESTAMP + INTERVAL 5 DAY   DO TRUNCATE TABLE test.aaa;

  7) 5天后开启每天定时清空test表,一个月后停止执行:

CREATE EVENT e_test   ON SCHEDULE EVERY 1 DAY   STARTS CURRENT_TIMESTAMP + INTERVAL 5 DAY   ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH   DO TRUNCATE TABLE test.aaa;

  [ON COMPLETION [NOT] PRESERVE]可以设置这个事件是执行一次还是持久执行,默认为NOT PRESERVE。

  8) 每天定时清空test表(只执行一次,任务完成后就终止该事件):

CREATE EVENT e_test   ON SCHEDULE EVERY 1 DAY   ON COMPLETION NOT PRESERVE   DO TRUNCATE TABLE test.aaa;

  [ENABLE | DISABLE]可是设置该事件创建后状态是否开启或关闭,默认为ENABLE。

  [COMMENT 'comment']可以给该事件加上注释。

  三、修改事件(ALTER EVENT)

ALTER EVENT event_name   [ON SCHEDULE schedule]   [RENAME TO new_event_name]   [ON COMPLETION [NOT] PRESERVE]   [COMMENT 'comment']   [ENABLE | DISABLE]   [DO sql_statement]

  1) 临时关闭事件

ALTER EVENT e_test DISABLE;

  2) 开启事件

ALTER EVENT e_test ENABLE;

  3) 将每天清空test表改为5天清空一次:

ALTER EVENT e_test   ON SCHEDULE EVERY 5 DAY;

  四、删除事件(DROP EVENT)

  语法很简单,如下所示:

DROP EVENT [IF EXISTS] event_name

  例如删除前面创建的e_test事件

DROP EVENT e_test;

  当然前提是这个事件存在,否则会产生ERROR 1513 (HY000): Unknown event错误,因此最好加上IF EXISTS

DROP EVENT IF EXISTS e_test;
    、查看事件(SHOW EVENTS)

  六、后续

  该特性确实非常有用,可作为定时清空数据表、监控主从服务器、汇总数据到另一张表等等,并且可以精确到每秒,实时性也可以得到保障。

  评论这张
 
阅读(786)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018