每天早上8点自动备份数据库,每周日凌晨3点清理过期日志,每月1号凌晨统计上月销售数据...这些重复性工作如果全靠人工操作,不仅效率低下还容易出错。MySQL定时任务(Event Scheduler)就是为解决这类问题而生的利器。
我在电商平台做DBA时,曾遇到过因人工忘记执行月度统计导致报表延误的情况。自从全面启用MySQL事件后,这类问题再没发生过。通过合理设置,可以让数据库在预定时间自动完成:
MySQL的事件调度器由三个关键部分组成:
sql复制-- 查看事件调度器状态
SHOW VARIABLES LIKE 'event_scheduler';
事件触发支持两种模式:
AT '2023-08-20 23:59:59'EVERY 1 DAY STARTS '2023-08-20 00:00:00'重要提示:事件执行时间基于服务器系统时间,跨国业务需特别注意时区设置
首先确保事件调度器已启用:
sql复制-- 临时启用(重启失效)
SET GLOBAL event_scheduler = ON;
-- 永久启用(修改my.cnf)
[mysqld]
event_scheduler=ON
这个例子实现每天凌晨3点全量备份:
sql复制DELIMITER //
CREATE EVENT daily_db_backup
ON SCHEDULE EVERY 1 DAY STARTS CURRENT_DATE + INTERVAL 3 HOUR
DO
BEGIN
SET @backup_file = CONCAT('/backups/mysql_', DATE_FORMAT(NOW(), '%Y%m%d'), '.sql');
SET @cmd = CONCAT('mysqldump -u backup_user -p"password" my_database > ', @backup_file);
SYSTEM @cmd;
-- 记录操作日志
INSERT INTO backup_logs(event_time, backup_path)
VALUES(NOW(), @backup_file);
END //
DELIMITER ;
更健壮的方案应该包含:
sql复制-- 每周日全量备份+每日增量备份
-- 备份文件自动压缩
-- 备份成功后发送通知邮件
-- 自动清理30天前的旧备份
sql复制-- 创建专用事件账号
CREATE USER 'event_admin'@'localhost' IDENTIFIED BY 'complex_password';
GRANT EVENT ON *.* TO 'event_admin'@'localhost';
建议配置:
sql复制-- 示例监控表结构
CREATE TABLE event_monitor (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
event_name VARCHAR(64) NOT NULL,
start_time DATETIME NOT NULL,
end_time DATETIME,
status ENUM('running','success','failed') DEFAULT 'running',
affected_rows INT,
error_message TEXT
);
事件未执行:
event_scheduler状态SHOW EVENTS ERROR事件执行卡死:
sql复制-- 查看正在执行的事件
SELECT * FROM performance_schema.events_waits_current;
ini复制# my.cnf优化建议
event_scheduler_interval=30 # 事件检查间隔(秒)
event_queue_size=1024 # 事件队列大小
sql复制-- 每月1号凌晨执行数据转换
CREATE EVENT monthly_etl
ON SCHEDULE
EVERY 1 MONTH
STARTS DATE_FORMAT(DATE_ADD(CURRENT_DATE, INTERVAL 1 MONTH), '%Y-%m-01 02:00:00')
DO
BEGIN
-- 步骤1:提取数据到临时表
-- 步骤2:数据清洗转换
-- 步骤3:加载到数据仓库
-- 步骤4:发送完成通知
END;
sql复制-- 每天同步用户订单到报表服务器
CREATE EVENT sync_order_data
ON SCHEDULE EVERY 1 DAY STARTS '23:00:00'
DO
BEGIN
-- 使用FEDERATED引擎同步数据
-- 或调用外部API推送数据
END;
bash复制#!/bin/bash
# 批量导出所有事件定义
mysql -u root -p -NBe "SHOW EVENTS" | awk '{print "SHOW CREATE EVENT "$2"."$1";"}' | mysql -u root -p > all_events.sql
建议将重要事件定义纳入Git管理:
我在实际运维中发现,对于执行时间超过5分钟的事件,最好拆分为多个子事件并通过状态表控制流程。曾经有个数据归档事件因单次处理量过大导致锁表,后来改为分批处理后就稳定多了。