MySQL定时事件)EVENT 应用总结

一、MySQL 定时事件(EVENT)应用总结

1. 核心作用

MySQL 事件是数据库内置定时任务,无需借助 Linux crontab、Windows 计划任务等外部工具,可直接在库内定时执行 DML/DDL 语句,常用于:

  1. 过期数据自动清理(日志、实时采集、历史工况表);
  2. 定时统计汇总报表、生成日 / 月统计数据;
  3. 定时更新状态、重置临时标记;
  4. 自动归档、迁移冷热数据。

2. 关键特性

  1. 调度规则:支持按分钟 / 小时 / 天 / 月循环,也可指定单次定点执行;
  2. 持久属性
    • ON COMPLETION PRESERVE:循环定时任务,执行完保留事件,下次继续运行;
    • ON COMPLETION NOT PRESERVE:一次性任务,执行完成自动删除事件;
  3. 开关依赖 :全局参数 event_scheduler=ON 才能生效,重启数据库会重置,需配置配置文件永久开启;
  4. 执行身份:以创建事件的用户权限运行,用户权限不足会执行失败;
  5. 事务特性BEGIN...END 代码块内多条语句为一个上下文,大批量删除建议分批,避免锁表、阻塞业务。

3. 适用场景 & 优缺点

适用场景

  • 业务采集海量时序数据(OEE、设备实时数据、传感器日志),需定期清理过期数据;
  • 轻量定时统计,不想额外部署定时脚本;
  • 数据库自闭环运维,减少外部调度依赖。

优点

  • 原生内置,无额外服务部署;
  • 与数据库事务、索引天然适配;
  • 建表、建事件脚本可统一版本管理。

缺点

  • 仅库内操作,无法调用外部程序、接口;
  • 大批量删除易产生大事务,影响线上读写性能;
  • 调度器关闭后任务暂停,无告警机制,需自行监控。

4. 生产使用规范

  1. 循环定时必须使用 PRESERVE
  2. 大表删除禁止一次性全删,采用 LIMIT 分批删除;
  3. 时间过滤字段建立索引,提升删除效率;
  4. 增加注释说明用途、执行时间;
  5. 创建时加 IF NOT EXISTS 防止重复创建报错;
  6. 上线前确认 event_scheduler 已永久开启。

二、带完整注释优化版定时清理事件 + 功能说明

完整带注释 SQL

sql

复制代码
-- 创建每日清理历史数据定时事件,不存在才创建,避免重复创建报错
CREATE EVENT IF NOT EXISTS cleanup_realtime_1d
-- 调度规则:每1天执行一次
ON SCHEDULE EVERY 1 DAY
-- 首次启动执行时间:2025-12-22 早上08:30,之后每日08:30自动运行
STARTS '2025-12-22 08:30:00.000'
-- 循环任务:执行完成后保留事件,保证第二天继续执行
ON COMPLETION PRESERVE
-- 创建后默认启用该定时事件
ENABLE
-- 事件注释:记录用途,方便后期维护查看
COMMENT '每日08:30分批清理oee_data_history表1天前的过期时序数据,避免一次性大量删除锁表'
DO
BEGIN
    -- 循环判断:表中是否存在超过1天的过期数据,有则持续删除
    WHILE EXISTS (SELECT 1 FROM oee_data_history WHERE _TIMESTAMP < DATE_SUB(NOW(), INTERVAL 1 DAY)) DO
        -- 每次仅删除1000条,拆分大事务,降低数据库锁竞争、减少binlog压力
        DELETE FROM oee_data_history WHERE _TIMESTAMP < DATE_SUB(NOW(), INTERVAL 1 DAY) LIMIT 1000;
        -- 删除一次休眠0.1秒,给数据库IO、业务读写留出缓冲时间,防止CPU/IO打满
        SLEEP 0.1;
    END WHILE;
END;

程序整体功能说明

  1. 定时规则 每天早上 08:30 自动触发执行,首次执行从 2025-12-22 08:30 开始,永久循环执行。
  2. 数据清理逻辑 针对 oee_data_history 设备 OEE 历史数据表,删除时间戳 _TIMESTAMP 早于当前时间 1 天的历史采集数据,只保留近 1 天数据。
  3. 性能优化逻辑 不一次性删除全部过期数据,采用循环分批删除,每次最多删 1000 条,每轮删除后短暂休眠,缓解数据库压力,避免大批量删除造成表锁、业务查询卡顿、大量日志写入。
  4. 容错与维护设计
    • 使用 IF NOT EXISTS 重复执行脚本不会报错;
    • 添加注释记录用途,方便运维排查;
    • PRESERVE 保证循环任务不会执行一次就消失;
    • 代码块闭合完整,语法无缺陷。
  5. 使用前提 MySQL 全局事件调度器 event_scheduler 必须开启,且 _TIMESTAMP 字段需建立索引加速过滤删除。