mysql使用事件做日志表数据转移

日志表的数据会随着系统的使用,数据量不断增加,时间久了之后,会导致日志表查询很慢,甚至根本打不了了。

为了缓解日志表数据量大导致无法查询或查询慢的问题,有个解决方法是定期把日志表数据剪切到历史记录表中。

下面以系统的 api接口日志表为例,说明具体的操作方法。

有两张表,接口日志表、接口日志历史记录表。每天定时把日志表一个月前的日志信息删除,插入到日志历史记录表中。这样可以保证日志表数据量不会太大,同时还能保留原来的日志数据。

两个表的创表语句:

sql 复制代码
CREATE TABLE `sys_interface_log` (
  `log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
  `interface_name` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '接口名称',
  `interface_url` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '调用地址',
  `request_body` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '请求参数',
  `request_time` datetime DEFAULT NULL COMMENT '请求时间',
  `response_body` longtext CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '返回参数',
  `response_time` datetime DEFAULT NULL COMMENT '返回时间',
  `call_status` int DEFAULT NULL COMMENT '接口调用状态(1:成功、0:失败)',
  `fail_reason` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '失败原因',
  `sms_notify` int DEFAULT NULL COMMENT '失败时通知发送情况(1:短信发送成功、0:短信发送失败)',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `batch_id` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '批次ID',
  `interface_system` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '接口对应的系统',
  PRIMARY KEY (`log_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=377 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='接口日志表';



CREATE TABLE `sys_interface_log_history` (
  `log_id` bigint DEFAULT NULL COMMENT '日志ID',
  `interface_name` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '接口名称',
  `interface_url` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '调用地址',
  `request_body` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '请求参数',
  `request_time` datetime DEFAULT NULL COMMENT '请求时间',
  `response_body` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '返回参数',
  `response_time` datetime DEFAULT NULL COMMENT '返回时间',
  `call_status` int DEFAULT NULL COMMENT '接口调用状态(1:成功、0:失败)',
  `fail_reason` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci COMMENT '失败原因',
  `sms_notify` int DEFAULT NULL COMMENT '失败时通知发送情况(1:短信发送成功、0:短信发送失败)',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `batch_id` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '批次ID',
  `interface_system` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '接口对应的系统'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC COMMENT='接口日志表-历史数据表';

创建事件

sql 复制代码
CREATE DEFINER=`root`@`%` EVENT `cleanup_interface_logs` ON SCHEDULE EVERY 1 DAY STARTS '2026-05-03 01:00:00' ON COMPLETION NOT PRESERVE ENABLE DO BEGIN
    -- 错误处理
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
    BEGIN
        ROLLBACK;
    END;
    
    -- 开始事务
    START TRANSACTION;
    
    -- 将1个月前的接口日志数据移动到历史表
    INSERT INTO sys_interface_log_history (
		  log_id,
			interface_name,
			interface_url,
			request_body,
			request_time,
			response_body,
			response_time,
			call_status,
			fail_reason,
			sms_notify,
			create_time,
			batch_id,
			interface_system
		)
    SELECT 
		  log_id,
			interface_name,
			interface_url,
			request_body,
			request_time,
			response_body,
			response_time,
			call_status,
			fail_reason,
			sms_notify,
			create_time,
			batch_id,
			interface_system
		FROM sys_interface_log 
    WHERE create_time < DATE_SUB(NOW(), INTERVAL 1 MONTH);
    
    -- 删除已移动的数据
    DELETE FROM sys_interface_log 
    WHERE create_time < DATE_SUB(NOW(), INTERVAL 1 MONTH);
		
		
		
		-- 将1个月前的发单接口日志数据移动到历史表
    INSERT INTO sys_bill_detail_log_history (
		  log_id,
			batch_id,
			interface_system,
			pay_play_id,
			recore_content,
			settle_status,
			fail_reason,
			sms_notify,
			create_time
		)
    SELECT 
		  log_id,
			batch_id,
			interface_system,
			pay_play_id,
			recore_content,
			settle_status,
			fail_reason,
			sms_notify,
			create_time
		FROM sys_bill_detail_log
    WHERE create_time < DATE_SUB(NOW(), INTERVAL 1 MONTH);
    
    -- 删除已移动的数据
    DELETE FROM sys_bill_detail_log
    WHERE create_time < DATE_SUB(NOW(), INTERVAL 1 MONTH);
		
    
    -- 提交事务
    COMMIT;
    
END

创建一个名为cleanup_interface_logs的事件,从2026-05-03开始,每天凌晨一点执行。

需要开启事件调度器

-- 查看事件调度器状态 SHOW VARIABLES LIKE 'event_scheduler';

-- 开启事件调度器(若为OFF) SET GLOBAL event_scheduler = ON;

查看事件的状态

-- 查看事件是否启用 SHOW EVENTS LIKE 'cleanup_interface_logs';

通过navicat可以直接编辑事件,操作如下:

选中事件,然后点击 设计事件,就可以编辑了。

也可以通过navicat图形化界面创建事件。

相关推荐
SelectDB7 分钟前
SelectDB 是哪个公司的?是国产数据库吗?一篇讲清飞轮科技与 Apache Doris 的关系
数据库
这个DBA有点耶16 分钟前
库内计算推理:一条SQL背后的算子融合,和外挂方案差了几次网络往返
数据库·人工智能·sql
这个DBA有点耶2 小时前
函数索引的“完全一致”有多苛刻:写法、字符集、类型,差一处就失效
数据库·mysql·代码规范
星恒随风2 小时前
MySQL 从零入门(三):表的约束详解
linux·服务器·数据库·笔记·mysql
Alluxio3 小时前
Alluxio + OCI:为 AI 工作负载实现亚毫秒访问延迟与可扩展吞吐
运维·数据库·人工智能·分布式·缓存·ai·语言模型
数据库急诊室_阿哲7 小时前
一次加索引建议的复核记录:从报告到签字
数据库·ai数据库
青瓦梦滋8 小时前
Redis主从复制
服务器·数据库·redis·缓存·bootstrap
慧都小妮子8 小时前
Wyn商业智能国产数据库适配:数据接入、分析缓存与审计日志验证清单
数据库·数据分析·数据可视化·审计日志·商业智能
Joy T9 小时前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
杨凯凡9 小时前
MySQL 死锁怎么排查?InnoDB 锁等待与 Spring Boot 整事务重试实战
数据库·spring boot·mysql