真实案例:Oracle数据库中表插入操作的审计
在Oracle 10g中某个用户下表OBJECT_ID_FACTORY 的记录再次出现重复。这是一张字典表,用于生成某些表的记录主键值。重复的键值导致了某些业务操作不能正常进行。
该问题以前出现过一次。通过logminer 也没能找到操作的应用,因此我们采用audit 技术来处理这个问题。
logminer的使用方法请见此文。链接: http://mikixiyou.iteye.com/blog/1514632
(miki西游 @mikixiyou 文档原文链接: http://mikixiyou.iteye.com/blog/1563796
)
1. 解决过程
在Oracle 10g 数据库中,此表的记录出现异常,无故增加了某条记录。我们使用logminer 无法查出是什么应用程序所为。因此,我们启用审计功能来捕捉错误的操作来解决这个问题。
Oracle 的审计功能是一个高级选项,默认是不开放的,需要修改审计类初始化参数来能使用。
第一步,检查审计类参数
SQL> show parameter audit
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest string /u01/app/oracle/admin/zxdb/adu
mp
audit_sys_operations boolean TRUE
audit_syslog_level string
audit_trail string DB
如果audit_trail 是空,则需要修改并重启实例使之生效后才能继续进行对象的审计操作。
调整审计结果的存储表aud$ 的表空间。原来是system 表空间,所以需要迁移到另外的表空间上,防止system 表空间暴涨不好收场。
SQL> alter table sys.aud$ move tablespace users;
第二步,设置对象操作的审计
审计mikixiyou 用户下表OBJECT_ID_FACTORY 每一次访问的插入操作,不管成功或失败,都记录下来;
审计 mikixiyou 用户下表OBJECT_ID_FACTORY 每一个会话的更新操作,不管成功或失败,都记录下来;
audit insert on mikixiyou .OBJECT_ID_FACTORY by access;
audit update on mikixiyou .OBJECT_ID_FACTORY; --by session [ WHENEVER [ NOT ] SUCCESSFUL ] 都可以省略掉。
第三步,检查哪些对象、哪些操作、哪些权限设置了审计
Select * from dba_stmt_audit_opts;
Select * from dba_priv_audit_opts;
Select * from dba_obj_audit_opts;
如这里 mikixiyou 用户下表OBJECT_ID_FACTORY 设置了insert 和update 的操作的审计
SQL> Select * from dba_obj_audit_opts;
OWNER OBJECT_NAME OBJECT_TYPE ALT AUD COM DEL GRA IND INS LOC REN SEL UPD REF EXE
CRE REA WRI FBK
------------------------------ ------------------------------ ----------------- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- --- -----
----- ----- ----- -----
mikixiyou OBJECT_ID_FACTORY TABLE -/- -/- -/- -/- -/- -/- A/A -/- -/- -/- S/S -/- -/-
-/- -/- -/- -/-
第四步,使用noaudit 取消对象操作的审计
noaudit insert on mikixiyou .OBJECT_ID_FACTORY by access;
noaudit update on mikixiyou .OBJECT_ID_FACTORY;
如果审计目标已经实现,需要及时关闭审计设置。这点很重要,需在实现过程中予以注意。
第五步,检查审计结果
在审计设置完成后,定期去查看视图dba_audit_trail 的记录情况。
SQL> desc dba_audit_trail;
名称 是否为空 ? 类型
----------------------------------------- -------- ----------------------------
OS_USERNAME VARCHAR2(255)
USERNAME VARCHAR2(30)
USERHOST VARCHAR2(128)
TERMINAL VARCHAR2(255)
TIMESTAMP DATE
OWNER VARCHAR2(30)
OBJ_NAME VARCHAR2(128)
ACTION NOT NULL NUMBER
ACTION_NAME VARCHAR2(28)
NEW_OWNER VARCHAR2(30)
NEW_NAME VARCHAR2(128)
OBJ_PRIVILEGE VARCHAR2(16)
SYS_PRIVILEGE VARCHAR2(40)
ADMIN_OPTION VARCHAR2(2)
GRANTEE VARCHAR2(30)
AUDIT_OPTION VARCHAR2(40)
SES_ACTIONS VARCHAR2(19)
LOGOFF_TIME DATE
LOGOFF_LREAD NUMBER
LOGOFF_PREAD NUMBER
LOGOFF_LWRITE NUMBER
LOGOFF_DLOCK VARCHAR2(40)
COMMENT_TEXT VARCHAR2(4000)
SESSIONID NOT NULL NUMBER
ENTRYID NOT NULL NUMBER
STATEMENTID NOT NULL NUMBER
RETURNCODE NOT NULL NUMBER
PRIV_USED VARCHAR2(40)
CLIENT_ID VARCHAR2(64)
ECONTEXT_ID VARCHAR2(64)
SESSION_CPU NUMBER
EXTENDED_TIMESTAMP TIMESTAMP(6) WITH TIME ZONE
PROXY_SESSIONID NUMBER
GLOBAL_UID VARCHAR2(32)
INSTANCE_NUMBER NUMBER
OS_PROCESS VARCHAR2(16)
TRANSACTIONID RAW(8)
SCN NUMBER
SQL_BIND NVARCHAR2(2000)
SQL_TEXT NVARCHAR2(2000)
SQL>
注意,该视图是建立在sys.aud$ 表之上,最好定期去转存清理它的数据。
2. 小结
这个只是 Oracle 中一种普通的审计方法。它可以监控到数据库中表一级对象的增删改查等操作。该功能由来已久,在 10g 开始,增加了一种更细致的审计方法,可以监控到表中记录一级的增删改查操作。
这种方法称之为细粒度审计,在有些场合能使用到。
更完整的审计设置和细粒度审计设置,可以参考此文,链接http://mikixiyou.iteye.com/blog/1547353
当然,您可以去参考oracle.doc,那里更详细。