MySql中的事件

一、前言

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

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

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

SET GLOBAL event_scheduler = 1;

 ---或我们可以在配置my.ini文件 中加上 event_scheduler = 1

SET GLOBAL event_scheduler = ON;

来开启,也可以直接在启动命令加上“–event_scheduler=1”,例如:

mysqld ... --event_scheduler=1

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

1SHOW VARIABLES LIKE 'event_scheduler'; 23SELECT @@event_scheduler; 45SHOW PROCESSLIST;

二、创建事件(CREATE EVENT)

先来看一下它的语法:

1CREATE EVENT [IF NOT EXISTS] event_name 2 ON SCHEDULE schedule 3 [ON COMPLETION [NOT] PRESERVE] 4 [ENABLE | DISABLE] 5 [COMMENT 'comment'] 6 DO sql_statement; 7 8schedule: 9 AT TIMESTAMP [+ INTERVAL INTERVAL] 10 | EVERY INTERVAL [STARTS TIMESTAMP] [ENDS TIMESTAMP] 11 12INTERVAL: 13 quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE | 14 WEEK | SECOND | YEAR_MONTH
  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秒钟后,再执行查询看看:

1mysql> SELECT * FROM aaa; 2+---------------------+ 3| timeline | 4+---------------------+ 5| 2007-07-18 20:44:26 | 6| 2007-07-18 20:44:27 | 7| 2007-07-18 20:44:28 | 8+---------------------+

2) 5天后清空test表:

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

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

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

4) 每天定时清空test表:

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

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

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

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

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

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

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

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

  1. 每天定时清空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)

1ALTER EVENT event_name 2 [ON SCHEDULE schedule] 3 [RENAME TO new_event_name] 4 [ON COMPLETION [NOT] PRESERVE] 5 [COMMENT 'comment'] 6 [ENABLE | DISABLE] 7 [DO sql_statement]
  1. 临时关闭事件

    ALTER EVENT e_test DISABLE;

  2. 开启事件

    ALTER EVENT e_test ENABLE;

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

    ALTER EVENT e_test

四、删除事件(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;

注意:如果你将event执行了Alter event event_name disable.那么当你重新启动mysql服务

器后,该event将被删除(测试版本:5.1.30)

应用案例

本案例是利用 event scheduler 的特性,每秒钟调用一次存储过程,用于判断 SLAVE 是否正常运行,如果发现 SLAVE 关闭了,忽略 0 次错误,然后重新启动 SLAVE。

首先创建存储过程

1delimiter // 2 create procedure `Slave_Monitor`() 3 begin 4 SELECT VARIABLE_VALUE INTO @SLAVE_STATUS 5 FROM information_schema.GLOBAL_STATUS 6 WHERE VARIABLE_NAME='SLAVE_RUNNING'; 7 IF ('ON' != @SLAVE_STATUS) THEN 8 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=0; 9 SLAVE START; 10 END IF; 11 end; // 12 delimiter ;

由于存储过程中无法调用类似 SHOW SLAVE STATUS 这样的语句,因此无法得到确切的复制错误信息和错误代码,不能进一步的处理 SLAVE 停止的各种情况。

接着,创建任务

1CREATE EVENT IF NOT EXISTS `Slave_Monitor` 2 ON SCHEDULE EVERY 5 SECOND 3 ON COMPLETION PRESERVE 4 DO 5 CALL Slave_Monitor();

 创建了一个任务,每 5秒钟执行一次,任务结束后依旧保留该任务,而不是删除。当然了,在本例中的任务不会结束,除非将它手动禁止了。

如果在运行中想要临时关闭一下某个任务,执行 ALTER EVENT 语句即可:

1(root:localhost:)test> alter event `Slave_Monitor` ON 2 COMPLETION PRESERVE DISABLE; 3 (root:localhost:)test> alter event `Slave_Monitor` ON 4 COMPLETION PRESERVE ENABLE;
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

mysql设置时区

mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0