zoukankan      html  css  js  c++  java
  • MySQL定时器Events

    一、背景

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

      在MySQL作业的执行过程中有一个问题是让人比较郁闷的,就是如果频率很快,快到作业还没有执行完成的话,作业就会被重复执行,这点跟SQL Server的不一样的,如果想达到类似SQL Server作业的串行效果,只有当作业执行完毕,下一个迭代才会开始。后来经过一些设计可以解决了MySQL作业重复执行的问题,你可以参考:MySQL表数据迁移自动化

    二、使用过程

    (一)  查看当前是否已开启事件计划(调度器)有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表示关闭;

    提醒:虽然这里用set global event_scheduler = on语句开启了事件,但是每次重启电脑。或重启mysql服务后,会发现,事件自动关闭(event_scheduler=OFF),所以想让事件一直保持开启,最好修改配置文件,让mysql服务启动的时候开启时间,只需要在my.ini配置文件的[mysqld]部分加上event_scheduler=ON 即可,如下:

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

      单独使用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;

     

    (Figure1:user表的Event_priv权限)

    获取当前登陆的用户和数据库:SELECT CURRENT_USER(), SCHEMA();

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

    Error Code: 1044

    Access denied for user 'bfsql'@'%' to database 'blog'

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

    UPDATE mysql.user SET Event_priv = 'Y' WHERE HOST='%' AND USER='bfsql';

    如果你这个时候再次执行创建Event的SQL,还是会出现上面的错误,因为你需要执行:

    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 #每隔30秒执行一次
    #ON SCHEDULE AT '2016-01-17 15:30:00' ON COMPLETION NOT PRESERVE ENABLE DO  #特定时间执行
    ON COMPLETION PRESERVE
    DO BEGIN
    CALL MoveBlogData();
    END$$
    DELIMITER ;

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

    (五)  事件开启与关闭:

    开启某事件:ALTER EVENT e_test ON COMPLETION PRESERVE ENABLE;

    关闭某事件:ALTER EVENT e_test ON COMPLETION PRESERVE DISABLE;

    三、其它知识点

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

    四、参考文献

    mysql event(语法解释)

    MYSQL EVENT 使用手册(示例)

    MySQL-Events-CN(全面)

    MySQL事件调度器Event Scheduler  

    mysql access denied for user 'root'@' % ' to database

    mysql中的 skip-name-resolve 问题

    with admin option 和with grant option

    MySQL存储过程详解  mysql 存储过程

     mysql 让一个存储过程定时作业的代码

  • 相关阅读:
    Java 堆和栈 垃圾回收 2015/9/16
    多态 Java 2015/9/16
    学校项目过程中知识点 Java 2015/9/15 晚
    Python print输出不换行
    Windows 加载EXT分区
    RouterOS 安全模式
    RouterOS Openswan l2tp ipsec
    RouterOS 自动邮件备份脚本
    python chnroutes ROS版
    Kinect 2.0&Speech 11 中文语音控制
  • 原文地址:https://www.cnblogs.com/duanxz/p/3506422.html
Copyright © 2011-2022 走看看