--启用sys审计
alter system set audit_sys_operations='TRUE'
--启用db审计
alter system set audit_trail='DB_EXTENDED' scope=spfile ;
--迁移aud$表到用户自定义表空间
BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location( audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD, audit_trail_location_value => 'DBADMIN');
END;
--迁移FGA_LOG$表到用户自定义表空间
BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location( audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD, audit_trail_location_value => 'DBADMIN');
END;
--ddl audit trigger
CREATE OR REPLACE TRIGGER "SYS"."DDL_AUDIT_TRIGGER" AFTER DDL ON DATABASE DECLARE
Session_Id_Var NUMBER;
Os_User_Var VARCHAR2(200);
PROGRAM_Var VARCHAR2(200);
IP_Address_Var VARCHAR2(200);
Terminal_Var VARCHAR2(200);
Host_Var VARCHAR2(200);
Cut NUMBER;
Sql_Text ORA_NAME_LIST_T;
L_Trace NUMBER;
DDL_Sql_Var VARCHAR2(2000);
BEGIN
SELECT SYS_CONTEXT('USERENV','SESSIONID'),SYS_CONTEXT('USERENV','OS_USER'),SYS_CONTEXT('USERENV','MODULE'),SYS_CONTEXT('USERENV','IP_ADDRESS'), SYS_CONTEXT('USERENV','TERMINAL'), SYS_CONTEXT('USERENV','HOST') INTO Session_Id_Var,Os_User_Var,PROGRAM_Var,IP_Address_Var,Terminal_Var,Host_Var FROM DUAL;
BEGIN
SELECT COUNT(*) INTO L_Trace FROM DUAL WHERE ORA_DICT_OBJ_NAME NOT LIKE 'MLOG%' AND ORA_DICT_OBJ_NAME NOT LIKE '%LOG' AND UTL_INADDR.GET_HOST_ADDRESS IS NOT NULL AND SYS_CONTEXT('USERENV','IP_ADDRESS') IS NOT NULL AND SYS_CONTEXT('USERENV','IP_ADDRESS') <> UTL_INADDR.GET_HOST_ADDRESS;
IF L_Trace > 0 THEN
Cut := ORA_SQL_TXT(Sql_Text);
FOR i IN 1..Cut LOOP DDL_Sql_Var := SUBSTR(DDL_Sql_Var || Sql_Text(i),1,2000);
END LOOP;
END IF;
EXCEPTION WHEN OTHERS THEN NULL;
END;
INSERT INTO system.Audit_DDL_OBJ(
Opr_Time,
Session_Id,
OS_User,
PROGRAM,
IP_Address,
Terminal,
Host,
User_Name,
DDL_Type,
DDL_Sql,
Object_Type,
Owner,
Object_Name,
sys_time
) VALUES (
SYSDATE,
Session_Id_Var,
Os_User_Var,
PROGRAM_Var,
IP_Address_Var,
Terminal_Var,
Host_Var,
ORA_LOGIN_USER,
ORA_SYSEVENT,
DDL_Sql_Var,
ORA_DICT_OBJ_TYPE,
ORA_DICT_OBJ_OWNER,
ORA_DICT_OBJ_NAME,
to_char(sysdate,'yyyymmdd'));
COMMIT;
EXCEPTION WHEN OTHERS THEN NULL;
END DDL_Audit_Trigger;
--ddl audit table
CREATE TABLE SYSTEM.AUDIT_DDL_OBJ (
OPR_TIME DATE,
SESSION_ID NUMBER,
OS_USER VARCHAR2(200),
PROGRAM VARCHAR2(200),
IP_ADDRESS VARCHAR2(200),
TERMINAL VARCHAR2(200),
HOST VARCHAR2(200),
USER_NAME VARCHAR2(30),
DDL_TYPE VARCHAR2(30),
DDL_SQL VARCHAR2(2000),
OBJECT_TYPE VARCHAR2(18),
OWNER VARCHAR2(30),
OBJECT_NAME VARCHAR2(128),
SYS_TIME VARCHAR2(20))
TABLESPACE DBADMIN ;
CREATE INDEX SYSTEM.IX_AUDIT_DDL_OBJECTNAME ON SYSTEM.AUDIT_DDL_OBJ (OBJECT_NAME) TABLESPACE DBADMIN ;
CREATE INDEX SYSTEM.IX_AUDIT_DDL_OPRTIME ON SYSTEM.AUDIT_DDL_OBJ (SYS_TIME) TABLESPACE DBADMIN ;
--定期清理audit log ,保留最近3个月的数据
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_DB_STD, default_cleanup_interval => 24);
ELSE DBMS_OUTPUT.PUT_LINE('Cleanup for Audit was already initialized');
END IF;
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB ( job_name => 'DAILY_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-90); END;',
start_date => sysdate,
repeat_interval => 'FREQ=HOURLY;INTERVAL=24',
enabled => TRUE,
comments => 'Create an archive timestamp' );
END;
BEGIN
DBMS_AUDIT_MGMT.CREATE_PURGE_JOB( AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD, AUDIT_TRAIL_PURGE_INTERVAL => 24,
AUDIT_TRAIL_PURGE_NAME => 'Daily_Audit_Purge_Job',
USE_LAST_ARCH_TIMESTAMP => TRUE );
END;
Oracle DBF单个文件超过32G的解决办法:
1.添加多个数据文件
alter tablespace XXXX add datafile '/usr/app/oracle/oradata/orcl/XXXX02.dbf' size 1024M autoextend on next 1024m maxsize unlimited;
2.修改限制
在Oracle10g之后,可以在建表空间的时候指定使用bigfile,以前都是smallfile,
bigfile在数据文件大小blocksize 2K的数据文件最大支持8TB,blocksize 32K的数据文件最大支持到128TB
create bigfile tablespace XXXX datafile '/usr/app/oracle/oradata/orcl/XXXX.dbf' size 1024M autoextend on next 1024m maxsize unlimited;
#验证
select TABLESPACE_NAME, BIGFILE from DBA_TABLESPACES;
审计日志迁移实操记录:
1.报错信息:
ORA-01653: unable to extend table SYS.AUD$ by 8192 in tablespace SYSTEM
ORA-02002: error while writing to audit trail
ORA-00604: error occurred at recursive SQL level 1
ORA-01653: unable to extend table SYS.AUD$ by 8192 in tablespace SYSTEM
2.问题原因分析
从报错信息来看,是system表空间不足,无法写入审计日志数据
3.解决方案
第一种:修改表空间大小
#查看数据文件路径
select name from v$datafile;
select * FROM dba_data_files;
#修改大小,不能超过32767M,超过会报错
Alter datebase datafile '数据文件名' resize 100G;
第二种:关闭审计功能
注意:关闭需要重启,会影响正使用的业务
#关闭审计功能
Alter system set audit_trail=FALSE scope=spfile;
#关闭
shutdown immediate;
#启动
startup;
第三种:创建新的表空间,对审计日志数据进行迁移分离
#登陆
SQLPLUS / AS SYSDBA
#查看审计功能是否开启
show parameter audit_trail;
show parameter audit;
###说明:
VALUE值为DB,表面审计功能为开启的状态
audit_trail=DB,代表的是,oracle将把每次审计跟踪记录在数据库的一张叫做AUD$的表中。
audit_trail=os , oracle将把每次审计跟踪记录在os文件系统中方便调取
VALUE值为FALSE,表面审计功能为关闭的状态
#检查当前审计表所在表空间
SELECT table_name, tablespace_name FROM dba_tables WHERE table_name IN ('AUD$', 'FGA_LOG$') ORDER BY table_name;
#检查审计表的数据量
select segment_name,bytes/1024/1024 size_in_megabytes from dba_segments where segment_name in ('AUD$','FGA_LOG$');
#检查当前所有表空间使用情况
select dba.TABLESPACE_NAME, sum(bytes)/1024/1024 as MB from dba_data_files dba group by dba.TABLESPACE_NAME;
#检查当前所有表空间使用率
select total.tablespace_name, round(total.MB, 2) as Total_MB, round(total.MB - free.MB, 2) as Used_MB, round((1-free.MB / total.MB)* 100, 2) || '%' as Used_Pct from (select tablespace_name, sum(bytes) /1024/1024 as MB from dba_free_space group by tablespace_name) free, (select tablespace_name, sum(bytes) / 1024 / 1024 as MB from dba_data_files group by tablespace_name) total where free.tablespace_name = total.tablespace_name order by used_pct desc;
#创建新的表空间,初始大小根据当前使用大小
create tablespace audit_tbs datafile SIZE 32057M autoextend ON NEXT 100M;
#迁移存储表
#使用存储过程:DBMS_AUDIT_MGMT.SET_AUDIT_TRAIL_LOCATION
#迁移aud$
SQL> BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,
audit_trail_location_value => 'AUDIT_TBS');
END;
/
#迁移FGA_LOG$表
SQL> BEGIN
DBMS_AUDIT_MGMT.set_audit_trail_location(
audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_FGA_STD,
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;
----------------------------------
#定时清理审计日志,作为参考,不要直接复制使用
#定期清理audit log ,保留最近3个月的数据
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_DB_STD, default_cleanup_interval => 24);
ELSE DBMS_OUTPUT.PUT_LINE('Cleanup for Audit was already initialized');
END IF;
END;
BEGIN
DBMS_SCHEDULER.CREATE_JOB ( job_name => 'DAILY_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-90); END;',
start_date => sysdate,
repeat_interval => 'FREQ=HOURLY;INTERVAL=24',
enabled => TRUE,
comments => 'Create an archive timestamp' );
END;
BEGIN
DBMS_AUDIT_MGMT.CREATE_PURGE_JOB( AUDIT_TRAIL_TYPE => DBMS_AUDIT_MGMT.AUDIT_TRAIL_DB_STD, AUDIT_TRAIL_PURGE_INTERVAL => 24,
AUDIT_TRAIL_PURGE_NAME => 'Daily_Audit_Purge_Job',
USE_LAST_ARCH_TIMESTAMP => TRUE );
END;
------------------------------------------------
#报错信息:
SQL> BEGIN
2 DBMS_AUDIT_MGMT.set_audit_trail_location(audit_trail_type => DBMS_AUDIT_MGMT.AUDIT_TRAIL_AUD_STD,audit_trail_location_value => 'AUDIT_TBS');
3 END;
4 /
BEGIN
*
ERROR at line 1:
ORA-46267: Insufficient space in 'AUDIT_TBS' tablespace, cannot complete
operation
ORA-06512: at "SYS.DBMS_AUDIT_MGMT", line 1576
ORA-06512: at line 2
#报错信息分析:初始创建的表空间不足,需要调整创建的新表空间大小
#解决步骤如下:
#查看当前表空间的文件位置
SQL> select name from v$datafile;
NAME
+DATA/orcl/datafile/audit_tbs.305.1105719699
11 rows selected.
#调整大小,这个大小根据审计日志当前的数据大小,不小于当前数据大小
SQL> alter database datafile '+DATA/orcl/datafile/audit_tbs.305.1105719699' resize 5000m;
Database altered.
#经此调整后还是会有同样的问题,当前数据量已经超过32G,单个dbf文件最大只能32G,无法迁移成功,解决方法如下:
#删除新创建的表空间
DROP TABLESPACE audit_tbs INCLUDING CONTENTS AND DATAFILES;
#重新创建
create bigfile tablespace audit_tbs datafile size 35000M autoextend on next 100m maxsize unlimited;
#查看表空间是否是bigfile类型
select TABLESPACE_NAME, BIGFILE from DBA_TABLESPACES;
参考资料: