• MySQL事件调度器event的使用


    Q:假设,有一个需求,希望在某一个时刻系统调用一个begin end执行一下;十分钟以后执行一下begin end。亦或有一个需求,每个多长时间周期性执行begin end。那么这个时候该怎么办呢?

    A:

      在Linux里面可以使用at、crontab来实现上面的需求;MySQL里面也有这样的方法,就是event对象。

      也被称为MySQL事件调度器(Event Scheduler),可以在某一个时间点执行一个SQL语句或一个语句块(BEGIN ... END);或者每隔固定间隔重复执行。类似于Linux下的at、crontab或Windows下的Task Scheduler。

     

    那么如何使用event,步骤如下:

    1、开启数据库的event执行调度

    > 查看是否开启定时器

    mysql> show variables like '%event_scheduler%';
    +-----------------+-------+
    | Variable_name   | Value |
    +-----------------+-------+
    | event_scheduler | OFF   |
    +-----------------+-------+

    >开启

    0:off

    1:on

    mysql> set global event_scheduler=1;
    mysql> exit
    Bye
    
    [root@studying ~]# mysql -uroot -p123
    
    mysql
    > show variables like '%event_scheduler%'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | ON | +-----------------+-------+

    注意:

      如果是设定事件计划为0 或OFF,即关闭事件计划进程的时候,不会有新的事件执行,但现有的正在运行的事件会执行到完毕。

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

     

    2、CREATE EVENT创建

    CREATE
      [DEFINER = { user | CURRENT_USER }]
    EVENT
      [IF NOT EXISTS]
    event_name
    ON SCHEDULE schedule
      [ON COMPLETION [NOT] PRESERVE]
      [ENABLE | DISABLE | DISABLE ON SLAVE]
      [COMMENT 'comment']
    DO event_body;
    
    schedule:
      AT timestamp [+ INTERVAL interval] ...
      |EVERY interval
      [STARTS timestamp [+ INTERVAL interval] ...]
      [ENDS timestamp [+ INTERVAL interval] ...]
     
    
    interval:
      quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
            WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
            DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

    详细解析:

    definer:指明该event的用户,服务器在执行该事件时,使用该用户来检查权限。

      默认用户为当前用户,即definer = current_user;

      如果明确指明了definer,则必须遵循如下规则:

        1.如果没有super权限,唯一允许的值就是自己当前用户,而不能设置为其他用户。

        2.如果具有super权限,则可以指定任意存在的用户;如果指定的用户不存在,则事件在执行时会报错。

    if not exists:如果事件已经存在,则不会创建,也不会报错。

    on schedule子句:指定何时执行该事件,以及如何执行该事件

      1)at timestamp用于创建单次执行的事件,timestamp执行事件执行的时间(如果指定的时间是过去的时间,则会产生一个warning),时间可以是具体的时间字符串或者是一个datetime类型的表达式(如current_timestamp):

        如果要指定将来某个时间,直接使用at timestamp,例:at '2017-08-08 08:08:08';

        如果要指定将来某个时间间隔,可利用interval关键字(interval关键字可以进行组合,at timestamp + INTERVAL 2 HOUR、 + INTERVAL 30 MINUTE)

      2)every子句用于创建重复执行的事件,如果每分钟执行一次,则可以:EVERY 1 MINUTE。

        当然,every子句可以指定一个开始事件和结束时间,通过STARTS和ENDS关键字来表示,具体语法与前面类似

      例如:EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK。

    ④通常情况下,如果一个事件过期已过期,则会被立即删除。但是,create event定义中通过on completion preserve子句可以保留已过期的时间。

      默认:ON COMPLETION NOT PRESERVE,也就是不保存

    ⑤默认情况下,enable on slave,事件一旦创建后就立即开始执行;可以通过disable关键字来禁用该事件。

    comment子句用于给事件添加注释。

    do子句用于指示事件需要执行的操作,可以是一条SQL语句,也可以是被begin...end包括的语句块,也可以在语句块中调用存储过程。

    基本格式:

        CREATE EVENT event_name

        ON SCHEDULE  <schedule>

        DO <event_body>;

    mysql> create event my_event  
        -> on schedule every 10 second 
        -> do update myschema.mytable set mycol = mycol + 1; 

    示例:建立一个计划任务,每分钟往表t2中添加数据(当前时间)

    mysql> show events;
    Empty set (0.02 sec)
    
    mysql> create table t2(id int auto_increment primary key,t_time datetime);
    
    mysql> delimiter $$
    mysql> CREATE EVENT e_daily
        ->   ON SCHEDULE
        ->   EVERY 1 MINUTE
        ->     COMMENT 'Saves total number of sessions then clears the table each day'
        ->   DO
        ->     BEGIN
        ->       INSERT INTO t2 values (null,current_timestamp);
        ->     END $$
    mysql> delimiter ;
    
    ……过一段时间……
    
    mysql> select * from t2;
    +----+---------------------+
    | id | t_time              |
    +----+---------------------+
    |  1 | 2017-04-04 18:02:38 |
    |  2 | 2017-04-04 18:03:38 |
    |  3 | 2017-04-04 18:04:38 |
    
    …………

     

    3、查看新建的计划任务

    mysql> select EVENT_NAME,LAST_EXECUTED from information_schema.EVENTS;
    +------------+---------------------+
    | EVENT_NAME | LAST_EXECUTED       |
    +------------+---------------------+
    | e_daily    | 2017-04-04 18:02:38 |
    +------------+---------------------+
    
    mysql> show eventsG;
    *************************** 1. row ***************************
                      Db: db1
                    Name: e_daily
                 Definer: root@localhost
               Time zone: SYSTEM
                    Type: RECURRING
              Execute at: NULL
          Interval value: 1
          Interval field: MINUTE
                  Starts: 2017-04-04 18:02:38
                    Ends: NULL
                  Status: ENABLED
              Originator: 0
    character_set_client: utf8
    collation_connection: utf8_general_ci
      Database Collation: latin1_swedish_ci
    

    [root@studying
    ~]# tail -1 /var/log/mysqld.log 2017-04-04T08:01:16.311514Z 12 [Note] Event Scheduler: scheduler thread started with id 12

    通过查看MySQL日志,查看执行情况 。

     

    4、修改alter event

    ALTER 
        [DEFINER = { user | CURRENT_USER }] 
    EVENT event_name 
        [ON SCHEDULE schedule] 
        [ON COMPLETION [NOT] PRESERVE] 
        [RENAME TO new_event_name] 
        [ENABLE | DISABLE | DISABLE ON SLAVE] 
        [COMMENT 'comment'] 
        [DO event_body] 

      alter event语句可以修改事件的一个或多个属性,语法与create event语句完全相同,唯一不同的是可以对事件重命名,使用RENAME TO子句。

    例如:

      ALTER EVENT OLDDB.MYEVENT RENAME TO NEWDB.MYEVENT; 

     

    5、删drop event

    DROP EVENT [IF EXISTS] event_name;

    删除一个定义的事件。

  • 相关阅读:
    STM32CubeMX 使用
    Zookeeper集群搭建
    golang zookeeper监听事件报错
    git push 报错
    springboot使用postgresql模式下数据库表找不到
    不要在循环中访问数据库,这样会严重影响数据库性能
    SQL查询效率(Oracle)
    游标 数据集 效率比较
    oracle 视图
    INDEX SKIP SCAN 和 INDEX RANGE SCAN以及索引会失效
  • 原文地址:https://www.cnblogs.com/geaozhang/p/6821692.html
Copyright © 2020-2023  润新知