MYSQL定时任务使用手册

开发和管理数据库时,经常需要定时执行某些任务,比如每天备份数据库、每周统计报表等。MySQL提供了一个非常有用的工具,即事件调度器(Event Scheduler),可以帮助我们实现定时任务调度的功能。本文将介绍如何使用mysql的事件调度器实现定时任务调度,并提供相应的代码示例。注意MYSQL版本为5.1或以上才能使用此功能

1、开启事件调度器
1.1 在使用事件调度器之前,首先需要确认MySQL的事件调度器是否已经 开启。可以通过以下命令查看事件调度器的状态:
复制代码
方法一
select @@event_scheduler;

--方法二
show variables like 'event_scheduler';

SHOW VARIABLES LIKE 'event_scheduler';

如果结果为Off,则需要手动开启事件调度器。可以通过以下命令开启:

1.2 开启定时调度命令,如下命令开启,如果服务器重启以后,此配置未失效,我们在配置文件 中修改,开启调度命令
复制代码
-- 开启event事件:
-- 方法1
set GLOBAL event_scheduler=ON;
-- 方法2
set GLOBAL event_scheduler=1;

开启成功后,可以通过再次执行SHOW VARIABLES LIKE 'event_scheduler';命令来确认事件调度器已经开启。

1.3 (建议使用此方法)您也可以在MySQL配置文件(通常是my.cnf或my.ini)中设置:

mysqld

event_scheduler = ON

复制代码
您也可以在MySQL配置文件(通常是my.cnf或my.ini)中设置:

[mysqld]
event_scheduler = ON

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
character-set-server=utf8      
default-storage-engine=innodb
port=50002 
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# 2024-08-20 
event_scheduler = ON

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
2、创建定时任务,使用事件调度器创建定时任务需要执行以下步骤:
2.1 创建一个事件调度器

使用CREATE EVENT语句可以创建一个事件调度器。具体语法如下:

CREATE EVENT event_name

ON SCHEDULE schedule

ON COMPLETION \[NOT\] PRESERVE

ENABLE \| DISABLE

COMMENT 'string'

DO event_body;

其中event_name是事件的名称,schedule是调度周期,event_body是事件的具体操作。

2.1.1 设定调度周期

调度周期可以根据实际需求设定。以下是常用的调度周期:

  • 每秒钟执行一次:EVERY 1 SECOND
  • 每分钟执行一次:EVERY 1 MINUTE
  • 每小时执行一次:EVERY 1 HOUR
  • 每天执行一次:EVERY 1 DAY
  • 每周执行一次:EVERY 1 WEEK
  • 每个月执行一次:EVERY 1 MONTH

可以根据需求选择合适的调度周期。

2.1.2 编写事件的具体操作

在event_body部分编写具体的操作逻辑。可以使用SQL语句执行数据库操作,也可以调用存储过程或函数。

以下是一个示例的定时任务,每天凌晨3点备份数据库:

CREATE EVENT backup_event

ON SCHEDULE EVERY 1 DAY

STARTS '2022-01-01 03:00:00'

DO

BEGIN

|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 | DECLARE backup_file ``VARCHAR``(255); SET backup_file := CONCAT(``'/var/backup/db_'``, DATE_FORMAT(NOW(), ``'%Y%m%d_%H%i%s'``), ``'.sql'``); SET @sql := CONCAT(``'mysqldump -hlocalhost -uroot -ppassword dbname > '``, backup_file); PREPARE stmt ``FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |

END;

复制代码
CREATE EVENT backup_event
ON SCHEDULE EVERY 1 DAY
STARTS '2022-01-01 03:00:00'
DO
BEGIN


DECLARE backup_file VARCHAR(255);

SET backup_file := CONCAT('/var/backup/db_', DATE_FORMAT(NOW(), '%Y%m%d_%H%i%s'), '.sql');

SET @sql := CONCAT('mysqldump -hlocalhost -uroot -ppassword dbname > ', backup_file);

PREPARE stmt FROM @sql;

EXECUTE stmt;

DEALLOCATE PREPARE stmt;

END;

以上代码创建了一个名为backup_event的事件调度器,设定调度周期为每天执行一次。在event_body部分,首先定义了一个变量backup_file,用于存放备份文件的路径。然后使用CONCAT函数拼接备份文件路径,再使用SET语句将备份命令赋值给@sql变量。最后,使用PREPARE和EXECUTE语句执行备份命令。

2.2 创建任务的实例
复制代码
CREATE TABLE t_mysql_job (
  id INT AUTO_INCREMENT PRIMARY KEY,
  job_name VARCHAR(50) NOT NULL,
  job_description VARCHAR(100),
  job_status INT DEFAULT 0,
  create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

CREATE EVENT job_10_minute_test
ON SCHEDULE EVERY 10 MINUTE
-- 从什么时候开始计时
STARTS SYSDATE()
DO
-- 在这里编写定时任务的逻辑代码
INSERT INTO t_mysql_job (job_name, job_description) VALUES ('Daily Job', 'This is a daily job');
2.2.1从当前时间延迟指定时间,每隔10分钟执行一次

以下SQL 用于创建一个循环事件,每个EVERY 10 MINUTE表示该事件每一分钟就执行一次,CURRENT_TIMESTAMP + INTERVAL 5 MINUTE表示从当前时间开始延迟五分钟再执行。

复制代码
create EVENT job_p_hr_attendance_daily
ON SCHEDULE
EVERY 10 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 10 MINUTE
ON COMPLETION PRESERVE
DO  call  p_hr_attendance_daily
;
2.2.2 指定某个时间开始,每隔5分钟执行一次
复制代码
CREATE EVENT DelayedSchedulingEvent
ON SCHEDULE
EVERY 5 MINUTE STARTS '2024-03-22 10:10:00'
ON COMPLETION PRESERVE
DO INSERT INTO `template_backend`.`message` (`message`, `message_date`) values ('指定时间2024-03-22 10:10:00后,每隔1分钟执行', now());
3、管理定时任务

使用CREATE EVENT语句创建了定时任务后,可以通过以下命令进行管理:

  • 查看所有事件调度器:SHOW EVENTS;
  • 查看指定事件调度器的信息:SHOW EVENT event_name;
  • 启用事件调度器:ALTER EVENT event_name ENABLE;
  • 禁用事件调度器:ALTER EVENT event_name DISABLE;
  • 修改事件调度器的执行时间:ALTER EVENT event_name ON SCHEDULE AT 'date_time';

通过管理命令,可以方便地查看和管理定时任务。

3.1 查看执行事件,使用命令 show events,显示如下重要的信息

DB:表示用作与哪个库,Name是事件名称。

Definer:表示哪个用户权限执行。

Type:ONE TIME表示只执行一次。

status:ENABLE表示当前事件为可用状态。

复制代码
show events
4 定时任务查询(帐号要查询此表的权限)
4.1 执行以下命令来查询事件日志表:
复制代码
SELECT * FROM mysql.event;

复制代码

  1. 这将列出所有已经创建的事件及其相关信息,如事件名称、状态、创建时间、执行时间等。

  2. 如果想查看特定事件的执行历史,可以通过事件名称来筛选:

4.2 按事件名称来查询,执行记录
复制代码
--查询执行情况
SELECT * FROM mysql.event  ;
--查询执行情况
SELECT * FROM mysql.event WHERE name = 'your_event_name';
--查询执行情况
SELECT * FROM information_schema.EVENTS ;

如果不是管理员帐号,切换到管理员下,执行如下命令,给予如下权限,以后便可以查询event的权限

复制代码
grant select, insert,update,delete  on mysql.event   to 'mes'@'%';

实际案例代码

参考代码:

-- 创建事件调度器

CREATE EVENT backup_event

ON SCHEDULE EVERY 1 DAY

STARTS '2022-01-01 03:00:00'

DO

BEGIN

|-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 | DECLARE backup_file ``VARCHAR``(255); SET backup_file := CONCAT(``'/var/backup/db_'``, DATE_FORMAT(NOW(), ``'%Y%m%d_%H%i%s'``), ``'.sql'``); SET @sql := CONCAT(``'mysqldump -hlocalhost -uroot -ppassword dbname > '``, backup_file); PREPARE stmt ``FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; |

END;

-- 查看所有事件调度器

SHOW EVENTS;

-- 查看指定事件调度器的信息

SHOW EVENT backup_event;

-- 启用事件调度器

ALTER EVENT backup_event ENABLE;

-- 禁用事件调度器

ALTER EVENT backup_event DISABLE;

-- 修改事件调度器的执行时间

ALTER EVENT backup_event ON SCHEDULE AT '2023-01-01 03:00:00';

复制代码
CREATE DEFINER=`root`@`%` PROCEDURE `yuxiu_mes_prd`.`p_hr_attendance_daily`()
BEGIN
	
	DECLARE finished INTEGER DEFAULT 0;  
    DECLARE v_dept_code VARCHAR(100); 
    DECLARE v_dept_name VARCHAR(100);  
    DECLARE v_onjob_qty int;
    DECLARE v_onjob_qty_sum int default  0;  
    DECLARE v_attendance_actual_qty_sum int  default  0;   
	-- 计算在职人数
	DECLARE cur CURSOR FOR select
							dept_code,
							dept_name,
							COUNT(person_num) qty
						from
							md_person
						where
							status = '10'
						group by
							dept_code,
							dept_name;
	-- 声明NOT FOUND的处理程序  
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;  
   
    OPEN cur; -- 打开游标 
    
    execute_do: LOOP  
        FETCH cur INTO v_dept_code, v_dept_name,v_onjob_qty; -- 从游标中获取数据  
        IF finished THEN   
            LEAVE execute_do; -- 如果已经到达结果集的末尾,则退出循环  
        END IF;  
        -- 在这里可以对获取到的数据进行处理,比如打印出来 
        set v_onjob_qty_sum=v_onjob_qty_sum+v_onjob_qty; 
		INSERT
			INTO
			hr_attendance_daily(attendance_date,
			dept_code,
			dept_name,
			onjob_qty,
			attendance_required_qty,
			update_by,
			update_time)
	VALUES 
		(current_date,
		v_dept_code,
		v_dept_name,
		v_onjob_qty,	
		v_onjob_qty,
		'p_hr_attendance_daily',
		now()) ON DUPLICATE KEY
		UPDATE
			onjob_qty = v_onjob_qty,
			attendance_required_qty = v_onjob_qty,		
			update_by = 'p_hr_attendance_daily',
			update_time = now()
			;  
    END LOOP execute_do;  
   -- 更新出勤率
   update hr_attendance_daily set  attendance_rate=attendance_actual_qty/onjob_qty where attendance_date =CURRENT_DATE() ;				
 
  -- 计算出勤人数总数
  select  SUM(attendance_actual_qty) into  v_attendance_actual_qty_sum from hr_attendance_daily 
  where attendance_date =CURRENT_DATE() and dept_code<>'all' ;
 
 -- 计算所有出勤率
 		INSERT
			INTO
			hr_attendance_daily(attendance_date,
			dept_code,
			dept_name,
			onjob_qty,
			attendance_required_qty,
			attendance_actual_qty,
			attendance_rate,
			update_by,
			update_time)
	  VALUES 
		(current_date,
		'all',
		'all',
		v_onjob_qty_sum,	
		v_onjob_qty_sum,
		v_attendance_actual_qty_sum,
		v_attendance_actual_qty_sum/v_onjob_qty_sum,
		'p_hr_attendance_daily',
		now()) ON DUPLICATE KEY
		UPDATE
			onjob_qty = v_onjob_qty_sum,
			attendance_required_qty = v_onjob_qty_sum,
			attendance_actual_qty=v_attendance_actual_qty_sum,
			attendance_rate=v_attendance_actual_qty_sum/v_onjob_qty_sum,
			update_by = 'p_hr_attendance_daily',
			update_time = now()
			;  
  
 
END

执行查看JOB执行的情况

复制代码
--执行查看任务
select * from mysql.event  ;
select * from information_schema.events ;
show variables like 'event_scheduler';
相关推荐
广州智造3 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
技术宝哥6 小时前
Redis(2):Redis + Lua为什么可以实现原子性
数据库·redis·lua
学地理的小胖砸7 小时前
【Python 操作 MySQL 数据库】
数据库·python·mysql
dddaidai1237 小时前
Redis解析
数据库·redis·缓存
数据库幼崽7 小时前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd8 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
betazhou8 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh9 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵10 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多11 小时前
Linux——mysql主从复制与读写分离
数据库·mysql