mysql event 默认不生效是因为 event_scheduler 变量默认为 off;需手动执行 set global event_scheduler = on 临时启用,或在配置文件中添加 event_scheduler = on 并重启服务。

MySQL Event 为什么默认不生效?
直接创建 EVENT 后发现没运行,大概率是 event_scheduler 没开。它默认是 OFF,不是服务启动就自动启用的。
- 查状态:
SHOW VARIABLES LIKE 'event_scheduler';—— 返回OFF就得手动开 - 临时开启(重启失效):
SET GLOBAL event_scheduler = ON; - 永久生效:在
my.cnf或my.ini的[mysqld]段加一行event_scheduler = ON,然后重启 MySQL - 注意权限:执行
CREATE EVENT需要EVENT权限,不是所有账号都有
怎么写一个安全删除30天前日志的 EVENT?
别直接 DELETE FROM log_table WHERE create_time —— 大表可能锁表、慢、甚至 OOM。得控制删除节奏。
- 推荐分批删:用
LIMIT+ 循环逻辑(靠 EVENT 定期触发来模拟) - 示例语句(假设日志表叫
sys_log,时间字段是created_at):DELETE FROM sys_log WHERE created_at
- 必须带
ORDER BY才能和LIMIT合法共存(MySQL 5.7+ 要求) - 建 EVENT 时建议用
DEFINER显式指定高权限用户,避免将来因账号变更失效
CREATE EVENT 语句的关键参数怎么选?
核心是调度频率、起始时间、是否保留定义 —— 错一个就可能删错或漏删。
-
ON SCHEDULE EVERY 1 DAY:每天凌晨跑一次足够,别设成每小时,容易积压未删数据 -
STARTS '2024-01-01 02:00:00':显式指定首次执行时间,避免创建即触发(尤其测试环境) -
ON COMPLETION PRESERVE:保留 EVENT 定义,方便后续查看或修改;用DROP主动删,别依赖NOT PRESERVE -
DISABLE ON SLAVE:如果用了主从复制,加这句防止从库重复执行(但更稳妥的是只在主库开event_scheduler)
删完怎么确认效果?有没有静默失败风险?
EVENT 不报错不等于成功执行了 —— 它可能因权限不足、SQL 报错、或被自动禁用而静默停摆。
- 查是否启用:
SELECT * FROM information_schema.EVENTS WHERE EVENT_NAME = 'clean_old_logs';,看STATUS是ENABLED且LAST_EXECUTED有更新 - 查错误日志:MySQL 错误日志里搜
Event Scheduler或对应EVENT名,有 SQL 报错会记在这里 - 别依赖单次 DELETE 行数:加个简单计数器表或写入日志表记录每次删了多少行,否则某天删了 0 行你也发现不了
- 上线前务必在测试库用
SELECT COUNT(*)验证条件是否真能命中旧数据,避免created_at是字符串类型或时区不对导致全表无匹配
实际中最容易被忽略的是时区问题:NOW() 返回的是 MySQL 服务器时区的时间,如果应用写入日志用的是 UTC,而 MySQL 设置的是 SYSTEM(即系统本地时区),那 30 天的计算就偏了。要么统一时区,要么改用 UTC_TIMESTAMP() 配合 created_at 的存储格式对齐。











