天天看点

MySQL定时器Events

一、背景

我们mysql的表a的数据量已经达到1.6亿,由于一些历史原因,需要把表a的数据转移到一个新表b,但是因为这是线上产品,所以宕机时间需要尽量的短,在不影响数据持续入库的情况下,我希望能通过作业(定时器events)的形式慢慢搬迁这些数据。

二、使用过程

(一)  查看当前是否已开启事件计划(调度器)有3种方法:

1)     show variables like 'event_scheduler';

2)     select @@event_scheduler;

3)     show processlist;

(二)  开启事件计划(调度器)开关有4种方法:

1)     set global event_scheduler = 1;

2)     set @@global.event_scheduler = 1;

3)     set global event_scheduler = on;

4)     set @@global.event_scheduler = on;

键值1或者on表示开启;0或者off表示关闭;

(三)  关于事件计划的权限:

单独使用event调用sql语句时,查看和创建需要用户具有event权限,调用该sql语句时,需要用户具有执行该sql的权限。event权 限的设置保存在mysql.user表和mysql.db表的event_priv字段中。(flush privileges;)

当event和procedure配合使用的时候,查看和创建存储过程需要用户具有create routine权限,调用存储过程执行时需要使用excute权限,存储过程调用具体的sql语句时,需要用户具有执行该sql的权限。

select host,user,event_priv from mysql.user;

MySQL定时器Events

从figure1可以知道bfsql@%是没有event_priv权限的,在该用户下创建事件的时候会出现下面的错误:

error code: 1044access denied for user 'bfsql'@'%' to database 'blog'

如果出现上面的错误,执行下面的sql就可以给bfsql@%赋予创建event的权限:

MySQL定时器Events

update mysql.user set event_priv = 'y' where host='%' and user='bfsql';  

flush privileges;  

最后,你可以通过show grants for 'bfsql'@'%';查看所有权限;

(四)  创建事件:

1)     创建事件的语法如下:

create event [if not exists] event_name

on schedule schedule

[on completion [not] preserve]

[enable | disable]

[comment 'comment']

do sql_statement

2)     创建事件的示例如下:

delimiter $$

create event if not exists e_blog

on schedule every 30 second

on completion preserve

do begin

call moveblogdata();

end$$

delimiter ;

do sql_statement字段表示该event需要执行的sql语句或存储过程。这里的sql语句可以是复合语句,使用begin和end标识符将复合sql语句按照执行顺序放在之间。

MySQL定时器Events

--从现在开始每隔九天定时执行  

create  event event1  

on schedule every 9 day starts now()  

on completion preserve enable  

do  

    begin  

       call total();  

    end  

--每个月的一号凌晨1 点执行  

create  event event2     

on schedule every 1 month starts date_add(date_add(date_sub(curdate(),interval day(curdate())-1 day), interval 1 month),interval 1 hour)  

        call stat();  

---每个季度一号的凌晨2点执行  

create  event total_season_event  

on schedule every 1 quarter starts date_add(date_add(date( concat(year(curdate()),'-',elt(quarter(curdate()),1,4,7,10),'-',1)),interval 1 quarter),interval 2 hour)  

        call season_stat();  

--每年1月1号凌晨四点执行  

create  event total_year_event  

on schedule every 1 year starts date_add(date(concat(year(curdate()) + 1,'-',1,'-',1)),interval 4 hour)  

        call year_stat();  

(五)  事件开启与关闭:

开启某事件:alter event e_test on completion preserve enable;

关闭某事件:alter event e_test on completion preserve disable;

三、其它知识点

对于我们线上环境来说,使用event时,注意在主库上开启定时器,从库上关闭定时器,event触发所有操作均会记录binlog进行主从同步,从库上开启定时器很可能造成卡库。切换主库后之后记得将新主库上的定时器打开。