Oracle如何迁移、管理、清除Audit数据(AUD$和FGA_LOG$表)

 

Oracle如何迁移、管理、清除Audit数据(AUD$和FGA_LOG$表)

 

前言

版本:11.2.0.4.0。

Oracle 11G中没特殊要求还是要建议关闭审计功能:alter system set audit_trail = none scope=spfile  sid='*';

由于默认审计数据的AUD$和FGA_LOG$表在system表空间,在开启审计情况下,可能会导致AUD$表体积巨大导致system表空间不足。

如果不关闭审计,则建议将这两张表迁移至其他表空间。

 

如何迁移

在不关闭审计情况下,建议迁移AUD$和FGA_LOG$,根据How To Move The DB Audit Trails To A New Tablespace Using DBMS_AUDIT_MGMT? (Doc ID 1328239.1)有(示例):

表空间:
SELECT table_name, tablespace_name FROM dba_tables WHERE table_name IN ('AUD$', 'FGA_LOG$') ORDER BY table_name;

TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
AUD$                           SYSTEM
FGA_LOG$                       SYSTEM

段大小:
col segment_name for a25
set linesize 500
select segment_name,bytes/1024/1024 size_in_megabytes from dba_segments where segment_name in ('AUD$','FGA_LOG$');
SEGMENT_NAME              SIZE_IN_MEGABYTES
------------------------- -----------------
FGA_LOG$                              .0625
AUD$                                   4448

创建新的表空间用来存放AUD$以及FGA_LOG$表:

create tablespace audit_tbs datafile '+DATA' size 6G autoextend off uniform size 1M;

然后再移动表即可:

BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,--this moves table AUD$
audit_trail_location_value => 'AUDIT_TBS');
END;
/

BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD,--this moves table FGA_LOG$
audit_trail_location_value => 'AUDIT_TBS');
END;
/

SELECT table_name, tablespace_name FROM dba_tables WHERE table_name IN ('AUD$', 'FGA_LOG$') ORDER BY table_name;

 

备份

通过数据泵expdp来导出实现备份。

或者通过create table 用户.表名  tablespace 表空间 as select * from aud$ where ....

 

如何管理/清除

在不关闭审计情况下,建议定期对AUD$表做备份清理的动作,控制AUD$表体积。

发现有的第三方审计安全软件会对AUD$做读取操作(只能是全表,AUD$表没有索引(The Effect Of Creating Index On Table Sys.Aud$ (Doc ID 1329731.1)))。

Oracle建议使用dbms_audit_mgmt来管理AUD$表,这个包还能用来定制清理策略、清理数据等。

根据SCRIPT: Basic example to manage AUD$ table with dbms_audit_mgmt (Doc ID 1362997.1),有

如下(将脚本的内容复制到文件中,对其进行自定义并以sysdba身份运行。):

-- Example re-locating AUD$ and setting up a purge job

set serveroutput on

prompt First Step: init cleanup (if not already)

BEGIN
  IF NOT
      DBMS_AUDIT_MGMT.IS_CLEANUP_INITIALIZED(DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD) THEN
    dbms_output.put_line('Calling DBMS_AUDIT_MGMT.INIT_CLEANUP');
    DBMS_AUDIT_MGMT.INIT_CLEANUP(audit_trail_type         => dbms_audit_mgmt.AUDIT_TRAIL_AUD_STD,
                                 default_cleanup_interval => 24 * 7);
  else
    dbms_output.put_line('Cleanup for STD was already initialized');
  end if;
end;
/

prompt Relocate AUD$ to a dedicated tablespace AUDIT_DATA

begin
  DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION(audit_trail_type           => dbms_audit_mgmt.AUDIT_TRAIL_AUD_STD,
                                           audit_trail_location_value => 'AUDIT_DATA');
end;
/

prompt set last archive timestamp to a week before now

begin
  DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(audit_trail_type  => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                                             last_archive_time => sysdate - 7);
end;
/

prompt setup a purge job


BEGIN
  DBMS_AUDIT_MGMT.DROP_PURGE_JOB(AUDIT_TRAIL_PURGE_NAME => 'Standard_Audit_Trail_PJ');
  -- exception
  -- when others then
  -- null;
end;
/

BEGIN
  DBMS_AUDIT_MGMT.CREATE_PURGE_JOB(AUDIT_TRAIL_TYPE           => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                                   AUDIT_TRAIL_PURGE_INTERVAL => 24,
                                   AUDIT_TRAIL_PURGE_NAME     => 'Standard_Audit_Trail_PJ',
                                   USE_LAST_ARCH_TIMESTAMP    => TRUE);
END;
/

prompt Stop here if you use Audit Vault, otherwise press Enter
pause

prompt call DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP regularly to advance
prompt the last archive ts, Audit Vault will do this for you automatically

prompt Optionally Schedule automatic advancement of the archive timestamp

create or replace procedure set_archive_retention(retention in number default 7) as
begin
  DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(audit_trail_type  => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                                             last_archive_time => sysdate -
                                                                  retention);
end;
/

begin
  DBMS_SCHEDULER.disable('advance_archive_timestamp');
  DBMS_SCHEDULER.drop_job('advance_archive_timestamp');
  -- exception
  -- when others then
  -- null;
end;
/

BEGIN
  DBMS_SCHEDULER.create_job(job_name            => 'advance_archive_timestamp',
                            job_type            => 'STORED_PROCEDURE',
                            job_action          => 'SET_ARCHIVE_RETENTION',
                            number_of_arguments => 1,
                            start_date          => SYSDATE,
                            repeat_interval     => 'freq=daily',
                            enabled             => false,
                            auto_drop           => FALSE);
  dbms_scheduler.set_job_argument_value(job_name          => 'advance_archive_timestamp',
                                        argument_position => 1,
                                        -- one week, you can customize this line:
                                        argument_value => 7);
  DBMS_SCHEDULER.ENABLE('advance_archive_timestamp');
End;
/

BEGIN
  DBMS_SCHEDULER.run_job(job_name            => 'advance_archive_timestamp',
                         use_current_session => FALSE);
END;
/

-- end example

以上脚本通过自定义job来定期清理7天前的数据,可以访问清理Audit数据帮助理解各个步骤的意思。

也可以手工清理数据:

set serveroutput on

prompt First Step: init cleanup (if not already)

BEGIN
  IF NOT
      DBMS_AUDIT_MGMT.IS_CLEANUP_INITIALIZED(DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD) THEN
    dbms_output.put_line('Calling DBMS_AUDIT_MGMT.INIT_CLEANUP');
    DBMS_AUDIT_MGMT.INIT_CLEANUP(audit_trail_type         => dbms_audit_mgmt.AUDIT_TRAIL_AUD_STD,
                                 default_cleanup_interval => 24 * 7);
  else
    dbms_output.put_line('Cleanup for STD was already initialized');
  end if;
end;
/

begin
  DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP(audit_trail_type  => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                                             last_archive_time => sysdate - 7);
end;
/


BEGIN
  sys.DBMS_AUDIT_MGMT.clean_audit_trail(audit_trail_type        => sys.DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
                                        use_last_arch_timestamp => TRUE);
END;
/

 

我遇到的问题是审计是关闭的,但是由于关闭之前AUD$以及达到了7个多G的数据,使用上边手工清理语句,在执行斜体部分进行清理的时候清理时间达到了2个多小时,

并且高水位线并没有被回收,即select aud$表虽然记录为0但是依旧会访问7个多G的物理读(direct path read),需要再次通过如下动作回收高水位线:

11:41:52 SYS@xxxxxxx1(217)> select count(*) from AUD$;

  COUNT(*)
----------
         0

Elapsed: 00:00:20.40

14:17:08 SYS@xxxxxxx1(2211)> col SEGMENT_NAME for a35
14:21:08 SYS@xxxxxxx1(2211)> select segment_name,bytes/1024/1024 from dba_segments where segment_name='AUD$';

SEGMENT_NAME                        BYTES/1024/1024
----------------------------------- ---------------
AUD$                                           7632

Elapsed: 00:00:00.03
14:21:12 SYS@xxxxxxx1(2211)> alter table sys.aud$ enable row movement;

Table altered.

Elapsed: 00:00:00.26
14:21:27 SYS@xxxxxxx1(2211)> alter table sys.aud$ shrink space cascade;

Table altered.

Elapsed: 00:11:05.15
14:35:42 SYS@xxxxxxx1(2211)> alter table sys.aud$ disable row movement;

Table altered.

Elapsed: 00:00:00.07
14:36:18 SYS@xxxxxxx1(2211)> select segment_name,bytes/1024/1024 from dba_segments where segment_name='AUD$';

SEGMENT_NAME                        BYTES/1024/1024
----------------------------------- ---------------
AUD$                                              1

Elapsed: 00:00:00.02

 

Oracle虽然说尽量避免对AUD$做truncate操作,但是根据我网上查找资料,还是可以truncate的没问题。

至于FGA_LOG$表,How to cleanup the log table FGA_LOG$ ? (Doc ID 402528.1)表明可以直接delete或者truncate没问题,如下:

The FGA_LOG$ table can be deleted from or truncated to manage its space, for example:

SQL> connect / as sysdba
Connected.
SQL> truncate table fga_log$;
Table truncated.

Alternatively you can delete records based on the TIMESTAMP# (date) column as follows:


SQL> delete from fga_log$ where timestamp# < sysdate-14;

This deletes all rows older than 2 weeks.

Cleaning up the records in FGA_LOG$ is much like cleaning up audit records for standard auditing in table SYS.AUD$ .

至此。

 

posted @ 2021-02-19 15:38  PiscesCanon  阅读(2998)  评论(0编辑  收藏  举报