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 让一个存储过程定时作业的代码

  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/duanxz/p/3506422.html
Copyright © 2011-2022 走看看