问题背景:
用户通过数据库管理审计日志包DBMS_AUDIT_MGMT里面的存储过程CREATE_PURGE_JOB创建了定期清理审计日志数据的job,job每1小时执行一次,清理1天以前的审计表数据,运行了一段时间后,用户发现审计表AUD$里面的数据并没有减少过,表里面依然包含了1天以前的数据
创建job的语句,里面主要包含了以下两个job的创建,一个是用于设置删除审计日志的保留策略时间,另一个是执行定期清理审计日志数据的job
--设置保留时间点为sysdate-1
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'WEEKLY_AUDIT_ARCHIVE_TIMESTAMP',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(AUDIT_TRAIL_TYPE =>DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,LAST_ARCHIVE_TIME => sysdate-1); END;',
start_date => sysdate,
repeat_interval => 'FREQ=HOURLY;INTERVAL=1',
enabled => TRUE,
comments => 'Create an archive timestamp'
);
END;
/
--设置清理job
BEGIN
DBMS_AUDIT_MGMT.CREATE_PURGE_JOB(
AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,
AUDIT_TRAIL_PURGE_INTERVAL => 1 /* hours */,
AUDIT_TRAIL_PURGE_NAME => 'WEEKLY_AUDIT_PURGE_JOB',
USE_LAST_ARCH_TIMESTAMP => TRUE
);
END;
/
问题分析:
通过DBA_AUDIT_MGMT_CLEAN_EVENTS查看审计任务清理操作历史记录,发现近14天并没有任何的清理记录
set linesize 400
select *
from DBA_AUDIT_MGMT_CLEAN_EVENTS
where CLEANUP_TIME>sysdate-14;
通过dba_scheduler_jobs查看审计任务是否有在正常执行,定期清理审计任务WEEKLY_AUDIT_PURGE_JOB有在正常的执行并且没有产生错误,而用于设置删除审计日志的保留策略的任务WEEKLY_AUDIT_ARCHIVE_TIMESTAMP执行有报错failure_count为3
set linesize 500
col owner for a5
col job_name for a30
col last_start_date for a35
col last_run_duration for a35
col NEXT_RUN_DATE for a35
col JOB_ACTION for a60
select owner,job_name, last_start_date,last_run_duration,NEXT_RUN_DATE,enabled,state,FAILURE_COUNT,JOB_ACTION from dba_scheduler_jobs
where job_name in ('WEEKLY_AUDIT_ARCHIVE_TIMESTAMP','WEEKLY_AUDIT_PURGE_JOB') and owner='SYS';
查看后台alert日志里面WEEKLY_AUDIT_ARCHIVE_TIMESTAMP任何的执行报错trc,可以看到任务执行失败的原因是由于参数AUDIT_TRAIL_TYPE传入的值无效所导致的,那么这个执行错误会导致清理审计任务WEEKLY_AUDIT_PURGE_JOB执行出现异常吗
通过10046跟踪一下清理审计任务里面调用的存储过程执行步骤DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(3, TRUE);其中3表示'STANDARD AND FGA AUDIT TRAIL',TURE表示使用使用LAST_ARCH_TIMESTAMP
注:数字代表的含义
1=>'STANDARD AUDIT TRAIL'
2=>'FGA AUDIT TRAIL'
3=>'STANDARD AND FGA AUDIT TRAIL'
4=>'OS AUDIT TRAIL'
8=>'XML AUDIT TRAIL'
12=>'OS AND XML AUDIT TRAIL'
15=>'ALL AUDIT TRAILS'
alter session set tracefile_identifier='10046';
alter session set timed_statistics = true;
alter session set statistics_level=all;
alter session set max_dump_file_size = unlimited;
alter session set events '10046 trace name context forever,level 12';
BEGIN DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL(3, TRUE); END;
/
alter session set events '10046 trace name context off';
select tracefile from v$process where addr in (select paddr from v$session where sid in (select sid from v$mystat));
从跟踪的日志内容,可以看到几个关键的操作语句
1 分别确认审计类型'STANDARD AUDIT TRAIL(1)','FGA AUDIT TRAIL(2)'是否配置了DEFAULT CLEAN UP INTERVAL(21)
=====================
PARSING IN CURSOR #140049562652688 len=99 dep=1 uid=0 oct=3 lid=0 tim=1703661580138346 hv=625228760 ad='912d7d28' sqlid='bmrqf18kn8fys'
SELECT COUNT(PARAM_ID) FROM SYS.DAM_CONFIG_PARAM$ WHERE AUDIT_TRAIL_TYPE# = :B2 AND PARAM_ID = :B1
END OF STMT
BINDS #140049562652688:
Bind#0
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f5fd4901a70 bln=22 avl=02 flg=09
value=1
Bind#1
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f5fd4901aa0 bln=22 avl=02 flg=09
value=21
BINDS #140049562652688:
Bind#0
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f5fd4901a70 bln=22 avl=02 flg=09
value=2
Bind#1
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f5fd4901aa0 bln=22 avl=02 flg=09
value=21
PARAMETER# PARAMETER_NAME
---------- ------------------------------
16 AUDIT FILE MAX SIZE
17 AUDIT FILE MAX AGE
21 DEFAULT CLEAN UP INTERVAL
22 DB AUDIT TABLESPACE
23 DB AUDIT CLEAN BATCH SIZE
24 AUDIT MANAGEMENT TRACE LEVEL
26 OS FILE CLEAN BATCH SIZE
2 分别查询审计类型'STANDARD AUDIT TRAIL(1)','FGA AUDIT TRAIL(2)'类型的job执行频率
=====================
PARSING IN CURSOR #140049562646512 len=133 dep=1 uid=0 oct=3 lid=0 tim=1703661580141636 hv=2417321808 ad='91092270' sqlid='chw5pjq81atuh'
SELECT JOB_INTERVAL FROM SYS.DAM_CLEANUP_JOBS$ WHERE AUDIT_TRAIL_TYPE# = 1 OR AUDIT_TRAIL_TYPE# = 3 OR AUDIT_TRAIL_TYPE# = 15
END OF STMT
=====================
PARSING IN CURSOR #140049562646512 len=133 dep=1 uid=0 oct=3 lid=0 tim=1703661580183040 hv=1865887619 ad='91085038' sqlid='ddhymt9rmfbw3'
SELECT JOB_INTERVAL FROM SYS.DAM_CLEANUP_JOBS$ WHERE AUDIT_TRAIL_TYPE# = 2 OR AUDIT_TRAIL_TYPE# = 3 OR AUDIT_TRAIL_TYPE# = 15
3 分别查询审计类型'STANDARD AUDIT TRAIL(1)','FGA AUDIT TRAIL(2)'类型最近一次保留数据归档的时间LAST_ARCHIVE_TIMESTAMP,手动查询可以得到最近一次的保留数据归档时间为18-MAR-17 06.30.00.000000 AM
=====================
PARSING IN CURSOR #140049562622520 len=107 dep=1 uid=0 oct=3 lid=0 tim=1703661580142968 hv=3463648011 ad='9108fc38' sqlid='fb06smm7764sb'
SELECT LAST_ARCHIVE_TIMESTAMP FROM SYS.DAM_LAST_ARCH_TS$ WHERE RAC_INSTANCE# = 0 AND AUDIT_TRAIL_TYPE# = 1
END OF STMT
=====================
PARSING IN CURSOR #140049562620424 len=107 dep=1 uid=0 oct=3 lid=0 tim=1703661580183748 hv=1336332626 ad='91084558' sqlid='b360rg97udnak'
SELECT LAST_ARCHIVE_TIMESTAMP FROM SYS.DAM_LAST_ARCH_TS$ WHERE RAC_INSTANCE# = 0 AND AUDIT_TRAIL_TYPE# = 2
END OF STMT
4 根据步骤3查询到的保留归档归档时间,数据库DBID以及没错批量删除行数对存放'STANDARD AUDIT TRAIL(1)'类型审计数据的aud$以及存放'FGA AUDIT TRAIL(2)'类型审计数据的FGA_LOG$进行删除
=====================
PARSING IN CURSOR #140049562231512 len=150 dep=1 uid=0 oct=7 lid=0 tim=1703661580181995 hv=2183676821 ad='9108da08' sqlid='asr850y12hhwp'
DELETE FROM SYS.AUD$ WHERE DBID = 1111108938 AND NTIMESTAMP# < to_timestamp('2017-03-18 06:30:00', 'YYYY-MM-DD HH24:MI:SS.FF') AND ROWNUM <= 100000
END OF STMT
=====================
PARSING IN CURSOR #140049562231512 len=153 dep=1 uid=0 oct=7 lid=0 tim=1703661580193289 hv=1301594933 ad='91083a48' sqlid='f9wm5sj6t9htp'
DELETE FROM SYS.FGA_LOG$ WHERE DBID = 1111108938 AND NTIMESTAMP# < to_timestamp('2017-03-18 06:30:00', 'YYYY-MM-DD HH24:MI:SS.FF') AND ROWNUM <= 10000
END OF STMT
通过以上跟踪的清理审计存储过程执行步骤,我们可以了解到为什么aud$的数据没有被删除,因为清理审计的存储过程获取到的数据保留归档时间为2017年3月18号,只删除这个时间点之前的数据,所以aud$里面的数据 一直都存在
再看回用于设置删除审计日志的保留策略时间的任务WEEKLY_AUDIT_ARCHIVE_TIMESTAMP里面通过调用存储过程DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP修改审计数据的保留时间点,但由于每次都执行报错导致这个时间点没有进行更新一直为2017年3月18号
分析WEEKLY_AUDIT_ARCHIVE_TIMESTAMP执行的报错ORA-46250: Invalid value for argument 'AUDIT_TRAIL_TYPE',任务调用的存储过程参数AUDIT_TRAIL_TYPE 传入的类型为DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD
这个类型在官方是可以查到的,并没有传入类型名称错误的问题
在Oracle的MOS官方Known Issues When Using: DBMS_AUDIT_MGMT (Doc ID 804624.1)查到类似的相同报错,官方案例里面是执行清理保留策略CLEAR_LAST_ARCHIVE_TIMESTAMP时发生报错ORA-46250: Invalid value for argument,原因是LAST_ARCHIVE_TIMESTAMP的原始设置是分别为不同的审计类型STANDARD 和 FGA,不是同时设置针对 STANDARD和FGA,因此只能分别单独设置,不能一起设置
查看当前环境的配置STANDARD 和 FGA的确为分别设置的,不是同时设置类型'STANDARD AND FGA AUDIT TRAIL'
按照官方的问题原因方向,我尝试先清理了STANDARD 和 FGA的设置,再设置DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,但还是出现报错ORA-46250
SQL> select * from DBA_AUDIT_MGMT_LAST_ARCH_TS;
AUDIT_TRAIL RAC_INSTANCE LAST_ARCHIVE_TS
-------------------- ------------ ---------------------------------------------------------------------------
STANDARD AUDIT TRAIL 0 18-MAR-17 06.30.00.000000 AM +00:00
FGA AUDIT TRAIL 0 18-MAR-17 06.30.00.000000 AM +00:00
SQL> exec DBMS_AUDIT_MGMT.CLEAR_LAST_ARCHIVE_TIMESTAMP(DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD);
exec DBMS_AUDIT_MGMT.CLEAR_LAST_ARCHIVE_TIMESTAMP(DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD);
PL/SQL procedure successfully completed.
SQL>
PL/SQL procedure successfully completed.
SQL>
SQL> select * from DBA_AUDIT_MGMT_LAST_ARCH_TS;
no rows selected
SQL> BEGIN DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(AUDIT_TRAIL_TYPE =>DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,LAST_ARCHIVE_TIME => sysdate-1); END;
2 /
BEGIN DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(AUDIT_TRAIL_TYPE =>DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD,LAST_ARCHIVE_TIME => sysdate-1); END;
*
ERROR at line 1:
ORA-46250: Invalid value for argument 'AUDIT_TRAIL_TYPE'
ORA-06512: at "SYS.DBMS_AUDIT_MGMT", line 61
ORA-06512: at "SYS.DBMS_AUDIT_MGMT", line 2233
ORA-06512: at line 1
SQL> select * from DBA_AUDIT_MGMT_LAST_ARCH_TS;
no rows selected
SQL> select * from DAM_LAST_ARCH_TS$;
no rows selected
在查询审计类型的归档保留策略视图DBA_AUDIT_MGMT_LAST_ARCH_TS的定义语句时,发现了一点比较可疑的地方,在将基表DAM_LAST_ARCH_TS$列AUDIT_TRAIL_TYPE#审计日志类型对应的数字转化成具体的词语描述时,只有4种类型,没有类型3=>'STANDARD AND FGA AUDIT TRAIL'对应的具体转化
1=>'STANDARD AUDIT TRAIL',
2=>'FGA AUDIT TRAIL',
4=>'OS AUDIT TRAIL',
8=>'XML AUDIT TRAIL',
其他=>'UNKNOWN AUDIT TRAIL'
所以,我个人推测存储过程AUDIT_TRAIL_TYPE参数可能只支持传入上述的4种类型
问题解决:
修改WEEKLY_AUDIT_ARCHIVE_TIMESTAMP任务调用的存储过程参数AUDIT_TRAIL_TYPE 传入参数为DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD
BEGIN
DBMS_SCHEDULER.drop_JOB (
job_name => 'WEEKLY_AUDIT_ARCHIVE_TIMESTAMP'
);
END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'WEEKLY_AUDIT_ARCHIVE_TIMESTAMP',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(AUDIT_TRAIL_TYPE =>DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,LAST_ARCHIVE_TIME => sysdate-1); END;',
start_date => sysdate,
repeat_interval => 'FREQ=HOURLY;INTERVAL=1',
enabled => TRUE,
comments => 'Create an archive timestamp'
);
END;
/
通过10046跟踪可以看到SET_LAST_ARCHIVE_TIMESTAMP正常执行会更新表SYS.DAM_LAST_ARCH_TS$对应审计类型的LAST_ARCHIVE_TIMESTAMP,如果审计类型不存在,则会对应插入新的审计类型数据
=====================
PARSING IN CURSOR #140666447875168 len=353 dep=1 uid=0 oct=189 lid=0 tim=1703668333914660 hv=3297789402 ad='9396be08' sqlid='0q3pumg290jfu'
MERGE INTO SYS.DAM_LAST_ARCH_TS$ D USING (SELECT COUNT(AUDIT_TRAIL_TYPE#) R_CNT FROM SYS.DAM_LAST_ARCH_TS$ WHERE RAC_INSTANCE# = :B2 AND AUDIT_TRAIL_TYPE# = :B1 ) S ON (S.R_CNT = 1) WHEN MATCHED THEN UPDATE SET D.LAST_ARCHIVE_TIMESTAMP = :B3 WHERE D.RAC_INSTANCE# = :B2 AND D.AUDIT_TRAIL_TYPE# = :B1 WHEN NOT MATCHED
THEN INSERT VALUES(:B1 , :B2 , :B3 )
END OF STMT
PARSE #140666447875168:c=0,e=188,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=1,plh=0,tim=1703668333914660
BINDS #140666447875168:
Bind#0
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7fef76ef1b08 bln=22 avl=01 flg=09
value=0
Bind#1
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7fef76ef1aa8 bln=22 avl=02 flg=09
value=1
Bind#2
oacdty=180 mxl=11(11) mxlc=00 mal=00 scl=06 pre=00
oacflg=01 fl2=8206001 frm=00 csi=06 siz=16 off=0
kxsbbbfp=7fef74b80b10 bln=11 avl=07 flg=05
value=26-DEC-23 05.12.13 PM
Bind#3
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7fef76ef1b08 bln=22 avl=01 flg=09
value=0
Bind#4
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7fef76ef1aa8 bln=22 avl=02 flg=09
value=1
Bind#5
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7fef76ef1aa8 bln=22 avl=02 flg=09
value=1
Bind#6
oacdty=02 mxl=22(21) mxlc=00 mal=00 scl=00 pre=00
oacflg=13 fl2=206001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7fef76ef1b08 bln=22 avl=01 flg=09
value=0
Bind#7
oacdty=180 mxl=11(11) mxlc=00 mal=00 scl=06 pre=00
oacflg=01 fl2=8206001 frm=00 csi=06 siz=16 off=0
kxsbbbfp=7fef74b80ae8 bln=11 avl=07 flg=05
value=26-DEC-23 05.12.13 PM
设置数据保留时间点的任务WEEKLY_AUDIT_ARCHIVE_TIMESTAMP执行成功之后,定时清理审计的任务也可以正常删除数据了