(zz)mysql创建定时任务 一、前言 自 mysql5.1.6起,增加了一个非常有特色的功能–事件调度器(event scheduler),可以用做定时执行某些特定任务(例如:删除记录、对数据进行汇总等等),来取代原先只能由操作系统的计划任务来执行的工作。更值得 一提的是mysq
(zz)mysql创建定时任务
一、前言
自 mysql5.1.6起,增加了一个非常有特色的功能–事件调度器(event scheduler),可以用做定时执行某些特定任务(例如:删除记录、对数据进行汇总等等),来取代原先只能由操作系统的计划任务来执行的工作。更值得 一提的是mysql的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:linux下的cron或windows下的任务计划)只能精 确到每分钟执行一次。对于一些对数据实时性要求比较高的应用(例如:股票、赔率、比分等)就非常适合。
事件调度器有时也可称为临时触发器(temporal triggers),因为事件调度器是基于特定时间周期触发来执行某些任务,而触发器(triggers)是基于某个表所产生的事件触发的,区别也就在这里。
在使用这个功能之前必须确保event_scheduler已开启,可执行
set global event_scheduler = 1;
---或我们可以在配置my.cnf文件 中加上 event_scheduler = 1
或
set global event_scheduler = on;
来开启,也可以直接在启动命令加上“--event_scheduler=1”,例如:
mysqld ... --event_scheduler=1
要查看当前是否已开启事件调度器,可执行如下sql:
show variables like 'event_scheduler';
或
select @@event_scheduler;
或
show processlist;
二、创建事件(create event)
先来看一下它的语法:
1 create?event [ifnot?exists] event_name
2 ?onschedule schedule
3 [oncompletion [not] preserve]
4 [enable | disable]
5 [comment?'comment']
6 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}
1) 首先来看一个简单的例子来演示每秒插入一条记录到数据表
1 use test;
2 createtable?aaa (timeline?timestamp);
3 createevent e_test_insert
4 ?onschedule every 1?second
5 do?insertinto?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表:
1 create?event e_test
2 ?onschedule?at?current_timestamp?+ interval 5?day
3 do?truncatetable?test.aaa;
3) 2007年7月20日12点整清空test表:
1 create?event e_test
2 ?onschedule?at?timestamp?'2007-07-20 12:00:00'
3 do?truncatetable?test.aaa;
4) 每天定时清空test表:
1 create?event e_test
2 ?onschedule every 1?day
3 do?truncatetable?test.aaa;
5) 5天后开启每天定时清空test表:
1 create?event e_test
2 ?onschedule every 1?day
3 starts?current_timestamp+ interval 5?day
4 do?truncatetable?test.aaa;
6) 每天定时清空test表,5天后停止执行:
1 create?event e_test
2 ?onschedule every 1?day
3 ends?current_timestamp+ interval 5?day
4 do?truncatetable?test.aaa;
7) 5天后开启每天定时清空test表,一个月后停止执行:
1 create?event e_test
2 ?onschedule every 1?day
3 starts?current_timestamp+ interval 5?day
4 ends?current_timestamp+ interval 1?month
5 do?truncatetable?test.aaa;
[on completion [not] preserve]可以设置这个事件是执行一次还是持久执行,默认为not preserve。
8) 每天定时清空test表(只执行一次,任务完成后就终止该事件):
1 create?event e_test
2 ?onschedule every 1?day
3 ?oncompletion?not?preserve
4 do?truncatetable?test.aaa;
[enable | disable]可是设置该事件创建后状态是否开启或关闭,默认为enable。
[comment ‘comment’]可以给该事件加上注释。
三、修改事件(alter event)
1 alter?event event_name
2 [onschedule schedule]
3 [rename?tonew_event_name]
4 [oncompletion [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
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;
注意:如果你将event执行了alter event event_name disable.那么当你重新启动mysql服务
器后,该event将被删除(测试版本:5.1.30)
应用案例
本案例是利用 event scheduler 的特性,每秒钟调用一次存储过程,用于判断 slave 是否正常运行,如果发现 slave 关闭了,忽略 0 次错误,然后重新启动 slave。
* 首先创建存储过程
01 delimiter //
02 ?createprocedure?`slave_monitor`()
03 ?begin
04 ?selectvariable_value?into?@slave_status
05 ?frominformation_schema.global_status
06 ?wherevariable_name='slave_running';
07 if ('on'!= @slave_status)?then
08 ?setglobal?sql_slave_skip_counter=0;
09 slave start;
10 ?endif;
11 ?end; //
12 delimiter ;
由于存储过程中无法调用类似 show slave status 这样的语句,因此无法得到确切的复制错误信息和错误代码,不能进一步的处理 slave 停止的各种情况。
* 接着,创建任务
1 create?event ifnot?exists `slave_monitor`
2 ?onschedule every 5?second
3 ?oncompletion preserve
4 do
5 call slave_monitor();
创建了一个任务,每 5秒钟执行一次,任务结束后依旧保留该任务,而不是删除。当然了,在本例中的任务不会结束,除非将它手动禁止了。
*
如果在运行中想要临时关闭一下某个任务,执行 alter event 语句即可:
(root:localhost:)test> alter event `slave_monitor` on
completion preserve disable;
(root:localhost:)test> alter event `slave_monitor` on
completion preserve enable;