mysql 定时器

mysql定时器的使用场景

定时任务:

  • ​ 如定时清除日志表三个月之前的数据
  • ​ 凌晨1:00执行一次 日志表数据的删除

使用前的准备和注意事项

1.时间的问题

服务器Apache(PHP)时间和mysql的时间默认时区是跟我们中国的时区是不一样的,所以为了确保时间准确。时区这个玩意儿一定要设置

1.1Apache(PHP) 服务器时区的设置:

​ 找到php.ini 将 ";date.timezone =" 前面的分号去掉=号后面加上时区设置,然后重启apache服务既可。下面列出几个常用的时区

  • ​ Asia/Chongqing (重庆)

  • ​ Asia/Shanghai (上海)

  • ​ Asia/Urumqi(乌鲁木齐)

  • ​ Asia/Macao (澳门)

  • ​ Asia/Hong_Kong (香港)

  • ​ Asia/Taipei (台北)

例:

​ date.timezone = Asia/Shanghai

​ 上面这种是永久性修改,你也可以临时性修改具体可以自行百度

1.2mysql时区的修改

​ 方式有两种,推荐第二种(永久修改)

第一种:临时性修改
###第一种
select NOW();
##一:通过sql命令临时修改
set global time_zone = '+8:00';
set time_zone = '+8:00';
## 刷新内存中的时区,让修改立即生效,也可以通过重启服务达到
flush privileges;
select NOW();

​ 第二种:永久性修改

###二:修改my.cnf实现永久修改
# vi /etc/mysql/my.cnf
# 然后在mysqld下边的配置(Basic Settings)中添加一行:
default-time_zone = '+8:00'
#然后重启mysql

​ 重启完成后,可以再次使用sql 语句“select NOW();”来确认是否修改成功

2.检查mysql是否开启了定时器功能

2.1 查询定时器是否开启

#查看是否开启了event定时器功能
SHOW VARIABLES LIKE 'event_scheduler';

image-20191223144949216

可以看到定时的功能是没有开启的,在这种情况下就需要开启定时器功能

2.2开启mysql 定时器

开启mysql的定时器其实很简单,其实就是一句sql

#开启mysql定时器
set GLOBAL event_scheduler = 1;

最后检查状态如下图所示

image-20191223145517729

3.msyql定时器重启服务器或重启mysql 定时器失效的问题

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

window 上修改的方法

找到mysql 的my.ini配置文件,在mysqld 部分加上event_scheduler=ON

image-20191224101657548

ubuntu 16.04 上修改的方法

找到mysql的配置文件

vi /etc/mysql/mysql.conf.d/mysqld.cnf

在mysqld 部分加上event_scheduler=ON

image-20191224101413325

修改完成后,可以重启服务或重启服务器并通过2.1小节的方法来检查是否设置成功

mysql定时器的写法

​ 格式:

​ 参考https://dev.mysql.com/doc/refman/5.6/en/create-event.html

CREATE
    [DEFINER = user]
    EVENT
    [IF NOT EXISTS]
    event_name
    ON SCHEDULE schedule
    [ON COMPLETION [NOT] PRESERVE]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'string']
    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}

上面这是mysql 官方文档的格式介绍

其实,用伪sql 表示格式大概就是这样的

create 
	[DEFINER = 用户] # 不是所有用户都有权限创建定时器的,在这里指定用户,当然也可以不指定,这个选项是可选的
	event  #事件关键字
	
	[IF NOT EXISTS] #IF NOT EXISTS的含义CREATE EVENT与 CREATE TABLE:具有相同的含义 :如果event_name已经存在一个名为的事件 ,则不执行任何操作,也不会产生错误。(但是,在这种情况下会生成警告。) 可选
	
	event_name #事件名称
	
	ON SCHEDULE #设置定时的模式,有一次性(AT timestamp)的和持续性(EVERY interva)两种,这个选项为必须设置的
		schedule # 两种模式
			#AT timestamp 执行一次,可以使用DATETIME或 TIMESTAMP类型的值(这两种类型的值自行百度),例:AT '2019-12-23 15:30:00' 在这个时间执行一次操作
			
			#EVERY interva 重复执行
				interval #执行频率
				STARTS timestamp #开始时间
				ENDS timestamp #结束时间
				#例:EVERY 1 MINUTE STARTS '2019-12-23 15:30:00' ENDS '2019-12-23 16:00:00' 
				#从2019-12-23 15:30:00开始到2019-12-23 16:00:00 每分钟执行一次
				#也可以不写结束时间,那就是从什么时候开始一直执行

	[ON COMPLETION [NOT] PRESERVE] #事件执行之后是否会被drop掉设置
		#ON COMPLETION PRESERVE 当这个事件不会再发生的时候不会被Drop掉
		#ON COMPLETION NOT PRESERVE 当这个事件不会再发生的时候会被Drop掉
				
	[ENABLE | DISABLE | DISABLE ON SLAVE] #设置这个事件是否是活动状态
    	#ENABLE 创建完后就是已经开启的状态
        #DISABLE 创建完后是关闭的状态
        #DISABLE ON SLAVE 复制到从属服务器上的事件状态设置,指该事件已在主服务器上创建并复制到从属服务器,但未在从属服务器上执行(一般用不上,只有设置了mysql主从数据库才会用的上)
        
    [COMMENT 'string'] # 在这里写这个定时器是用来的干嘛的,相当于描述
    
    DO event_body;# DO 后面写你需要执行的sql
    	# 注意 DO 后面有两种写法
    	# 一种是直接写sql,这种只能在DO后面写一种sql
    	#另一种是 DO 后面再接BEGIN (sql1,sql2) END

下面我们创建一张用来测试我们的定时器的表

CREATE TABLE `test` (
	`id`  int NOT NULL ,
	`test`  varchar(255) NULL ,
	PRIMARY KEY (`id`)
)
;

例:

1.一次性定时器,将当前时间以字符串的形式插入到test表

DROP EVENT IF EXISTS `event_at`; #检查这个定时器是否存在,如果存在就删除
DELIMITER ;; # 修改sql语句结束符
#以root@localhost这个用户的身份创建一次性定时器,执行时间为2019-12-24 09:09:00
CREATE DEFINER=`root`@`localhost` EVENT `event_at` ON SCHEDULE AT '2019-12-24 09:09:00' 
ON COMPLETION NOT PRESERVE #当这个事件不会再发生的时候会被Drop掉
ENABLE # 创建时为开启状态
DO 
    INSERT INTO test(test) VALUES(date_format(now(), '%Y-%m-%d %H:%i:%s'));
;;
DELIMITER ;

过了执行时间之后,我们通过sql语句查询可以看到test表已经插入一条数据,如下结果:

image-20191224091629732

2.重复定时器,将当前时间以字符串的形式插入到test表

DROP EVENT IF EXISTS `event_minute`; #检查这个定时器是否存在,如果存在就删除
DELIMITER ;; # 修改sql语句结束符
#以root@localhost这个用户的身份创建重复性定时器,执行时间为2019-12-24 09:30:00 到 2019-12-24 09:35:30 ,执行频率为每分钟一次,执行结束后应该多6条数据,结束时间也可以不写,那就是从开始时间一直执行
CREATE DEFINER=`root`@`localhost` EVENT `event_minute` ON SCHEDULE EVERY 1 MINUTE STARTS '2019-12-24 09:30:00' ENDS '2019-12-24 09:35:30'
ON COMPLETION PRESERVE #当这个事件不会再发生的时候不会被Drop掉
ENABLE # 创建时为开启状态
DO 

BEGIN
    #这种格式可以写多条sql
    INSERT INTO test(test) VALUES(date_format(now(), '%Y-%m-%d %H:%i:%s'));
END
;;
DELIMITER ;

过了执行时间之后,我们通过sql语句查询可以看到test表已经插入6条数据,如下结果:

image-20191224094418853

3.重复定时器,删除日志表除了这个月的日志数据,只保留当月的数据

表结构如下:

image-20191224114412565

sql:

DROP EVENT IF EXISTS `event_day`; #检查这个定时器是否存在,如果存在就删除
DELIMITER ;; # 修改sql语句结束符
#以root@localhost这个用户的身份创建重复性定时器,从2019-12-24 11:50:00开始每周执行一次
CREATE DEFINER=`root`@`localhost` EVENT `event_day` ON SCHEDULE EVERY 1 DAY STARTS '2019-12-24 11:50:00'
ON COMPLETION PRESERVE #当这个事件不会再发生的时候不会被Drop掉
ENABLE # 创建时为开启状态
DO 

BEGIN
    #这种格式可以写多条sql
    delete from logs where `datetime` < str_to_date(concat(DATE_FORMAT(curdate(), '%Y-%m'), '-01'), '%Y-%m-%d') or `datetime` > last_day(curdate());
END
;;
DELIMITER ;

其他比较重要的sql

#关闭\打开定时器  ALTER EVENT 定时器名称 {DISABLE|ENABLE};
ALTER EVENT event_minute DISABLE; 
ALTER EVENT event_minute ENABLE;
#查询定时器状态
select * from mysql.event ;
posted @ 2019-12-24 10:00  makalo  阅读(1801)  评论(1编辑  收藏  举报