MySQL事件调度器的基本使用方法
根据MySQL的官方文档,从MySQL的5.1.6版本开始,MySQL支持了事件调度器,用于处理事件的调度与执行。触发器用于根据DML操作来触发事件,而事件调度器则是定时触发事件,功能类似于Linux的crontab计划任务,但是控制更为精确。在MySQL支持这项功能之前,往往通过Linux的crontab来辅助进行定时任务的触发,而当我们对于任务有更高的定时要求时,或者考虑调用接口处的性能瓶颈时,就需要使用到事件调度器(Event Scheduler)。
首先确保数据库选项event_scheduler处于开启状态。
show variables like 'event_scheduler';
如果我们看到ON,就表示这个功能处于开启状态,如果为OFF,表示关闭,DISABLED表示禁用。请注意,在数据库实例启动的情况下,我们可以随时在on和off间进行切换,但是,无法从on或off切换到disabled,也无法从disabled切换到on或off。只有在数据库关闭的状态下,这种转换才会生效。(DISABLED状态是在5.1.12版本中引入的)
set @@global.event_scheduler=on;
设置完成后,事件调度器就被开启了,实质上,是在MySQL实例中新建了一个事件调度器线程,通过show processlist\G命令,可以找到一个User为event_scheduler的线程,就表示事件调度器现在可以使用了。
接着我们随便创建一个存储过程,比如往某个表插入一条记录,好让事件调度器进行调度。
delimiter // create procedure `do_something`() begin insert into timelog values (); end; // delimiter ;
创建完毕后,我们就开始创建事件,事件最重要的部分有以下几个:
- 事件名称,这个很简单,就是给事件起个名字,加上IF NOT EXISTS的话,如果给定名称的事件已经存在了就不会再创建,并且只抛出一个Warning。
- 调度时间(ON SCHEDULE),可以定义事件被触发的具体时间,也可以指定事件被触发的周期,如果指定周期性任务,还可以指定开始时间和结束时间。
- 事件完成后的行为(ON COMPLETION),默认为NOT PRESERVED,即事件完成以后删除任务本身,注意,对于周期性的任务,不表示事件只做一次,而是指到达结束时间后,再删除这个事件。可以将它指定为PRESERVED,那么当事件完成以后,不会被删除。
- 事件体,就是事件具体需要做什么,定义方式和存储过程类似。
CREATE EVENT IF NOT EXISTS `log_every_minute` ON SCHEDULE EVERY 1 MINUTE ON COMPLETION PRESERVE DO CALL do_something();
在event_scheduler为on的情况下,事件一经创建就会生效。
这样,我们就成功创建了一个事件,每分钟会在timelog表中插入一条记录,当然,我们可以根据自己的需要,让MySQL去做一些更为复杂的任务。
MySQL InnoDB等待锁超时错误
当一个事务在请求某个资源时,它将待这个资源被解锁后继续操作,或者停止等待并返回错误:
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
事务将为一个资源解锁等待多长的时间,取决于innodb_lock_wait_timeout参数的设定,默认设置为50秒,最小允许值为1秒,如果将这个值设定为100000000以上的话,将禁用超时(无论等待多久都不会返回超时错误)。如果因为超时而返回了错误,那么当前SQL语句将会被回滚(在MySQL 5.0.12及以前的版本中,整个事务都将直接被回滚),用户程序可以再次尝试执行这条语句直到成功(通常会等一段时间再重试这个SQL语句),或者回滚整个事务并重新开始。
在InnoDB插件1.0.2之前,更改innodb_lock_wait_timeout选项的唯一方法是修改my.cnf或者my.ini配置文件中的相应选项,并重新启动数据库实例。
在InnoDB插件1.0.2及之后的版本中,还可以在MySQL实例运行时使用SET GLOBAL或者SET SESSION命令来更改innodb_lock_wait_timeout选项。更改GLOBAL设置需要SUPER权限,更改会影响所有在此更改之后新创建的的客户端Session,更改SESSION则只对当前客户端Session有效。