Oracle-审计表AUD$无法正常清理数据问题

问题背景:

        用户通过数据库管理审计日志包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;

Oracle-审计表AUD$无法正常清理数据问题_第1张图片

        通过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';

Oracle-审计表AUD$无法正常清理数据问题_第2张图片

        查看后台alert日志里面WEEKLY_AUDIT_ARCHIVE_TIMESTAMP任何的执行报错trc,可以看到任务执行失败的原因是由于参数AUDIT_TRAIL_TYPE传入的值无效所导致的,那么这个执行错误会导致清理审计任务WEEKLY_AUDIT_PURGE_JOB执行出现异常吗

Oracle-审计表AUD$无法正常清理数据问题_第3张图片

Oracle-审计表AUD$无法正常清理数据问题_第4张图片

        通过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

Oracle-审计表AUD$无法正常清理数据问题_第5张图片

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-审计表AUD$无法正常清理数据问题_第6张图片

        在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,因此只能分别单独设置,不能一起设置

Oracle-审计表AUD$无法正常清理数据问题_第7张图片

        查看当前环境的配置STANDARD 和 FGA的确为分别设置的,不是同时设置类型'STANDARD AND FGA AUDIT TRAIL'

Oracle-审计表AUD$无法正常清理数据问题_第8张图片

        按照官方的问题原因方向,我尝试先清理了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种类型

Oracle-审计表AUD$无法正常清理数据问题_第9张图片

问题解决:

        修改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执行成功之后,定时清理审计的任务也可以正常删除数据了

Oracle-审计表AUD$无法正常清理数据问题_第10张图片

你可能感兴趣的:(Oracle,数据库,oracle,dba,运维,问题分析)