数据库日志清理杂谈--在项目中如何高效实现日志清理

本文探讨了一种改进的日志清理方法,通过将清理规则存储于配置表并利用存储过程实现统一管理,有效解决了日志表数量增加带来的开发挑战。此方案简化了新增、修改和删除清理逻辑的操作,同时允许灵活配置清理周期,适用于不同需求场景。通过实例展示了存储过程的实现思路,包括异常处理与日志记录,并提出进一步优化方向,如按月清理及动态调整日志表名策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在项目当中,需要将某些数据记录在日志表中,以备审计或统计等。但日志表在保存过一段时间后,需要定时清理,而好多项目中,多采用数据库JOB针对每个日志表单独清理,这种方式的缺点:1)新增日志表清理开发工作量大;2)相同逻辑处理,但因清理周期不同,存在大量相同代码;3)如果屏蔽某个功能,不需要日志清理,屏蔽定时任务,开发工作量也比较大。。。

解决方法:可以将清理日志表相关的表名和清理周期等动态参数保存在数据库单独日志清理配置表中集中配置,相同逻辑处理放在Oracle存储过程中实现。这种实现方式的好处:1)新增日志表清理只需要增加日志清理配置表初始化脚本;2)日志清理逻辑放入一个存储过程中实现,新增、修改、删除日志清理,将风险降低最小;3)日志清理表中保存数据清晰,清理日志时间周期可动态配置。。。

见日志清理表的数据模型,T_ClearLogConfig。

column字段长度 nullablecomment
tableNamevarchar2(30)NO清理日志表名
timeColumnvarchar2(30)NO清理日志表的时间字段标识
saveDaysnumberNO日志保存天数
timeTypevarchar2(2) NO日志表时间类型1:字符型  2:日期型
timeFormatvarchar2(30) YES如果时间类型为字符型,该字段保存具体的时间格式 如:YYYY-MM-DD HH24:MI:SS
descriptionvarchar2(600) YES该字段不被使用,只保存描述,方便别人理解

将需要删除的日志表信息配置在上述表中,然后新增存储过程,根据上述表配置内容,执行清理操作。然后配置定时任务,在每天凌晨触发该存储过程。

存过实现思路如下(注意:实例中并没有记录异常信息,在项目当中,务必增加,否则存储过程执行异常,问题很难发现和定位)


create or replace procedure p_job_clearLog
as
    v_tableName t_clearLogConfig.tableName%type;
    --其他变量类似定义,不再一一列举
    cursor c_clearLog is
        select t.tableName, t.timeColumn, t.saveDays, t.timeType, t.timeFormat
        from t_clearLogConfig t;
    begin
        open c_clearLog;
        loop
            begin  --针对每一次清理日志进行异常捕获,防止清理某个日志失败,导致其他日志不能清理。应该将fetch into和exit语句放在begin外执行,sorry。
                 fetch c_clearLog into
                    v_tableName, v_timeColumn, v_saveDays, v_timeType, v_timeFormat;
                    exit when c_clearLog%notFound;

                     if v_timeType = '1' then  --如果时间类型为字符型
                        v_sql := 'delete from ' || v_tableName || ' where :timeColumn < to_char(trunc(sysdate - :saveDays), :timeFormat)';
                        execute immediate v_sql using v_timeColumn, v_saveDays, v_timeFormat;
                        commit;
                   elsif v_timeType = '2' then --时间类型为日期型
                        v_sql := 'delete from ' || v_tableName || ' where :timeColumn < sysdate - :saveDays';
                        execute immedidate v_sql using v_timeColumn, v_saveDays;
                        commit;
                end if;
            exception
                when others then
                   rollback;
                   --记录异常日志
        end loop;
        close c_clearLog;
    exception
        rollback;
       if c_clearLog%isOpen then
            close c_clearLog;
       end if;
       --记录日志
end p_job_clearJob;


思考其他几个问题:

    1)以上日志清理是以天为单位清理,但一般日志清理的周期都比较长,半年或者一年或更长时间清理一次,如果修改为按月为单位执行呢?

    2)在项目当中,好多日志保存在日志表时,日志表名是动态的,多以时间动态变化,如保存时日志名为t_log_201212,对这种情况如何修改实现呢?

说明:

    1)可以在日志清理表中增加是否清理标识,如果为清理标识,则清理该日志,否则不清理,可动态配置某日志是否清理。

    2)该文章只是个人的一些想法杂谈,如果您有什么好的想法或意见,欢迎交流。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值