zoukankan      html  css  js  c++  java
  • data object audit

    客户提出了一个需求。想对一个表做audit。 本来这是非常简单的一个case,因为oracle自带的 audit功能就可以非常方便的实现。  实现的方式如下:

    BEGIN
    	DBMS_FGA.ADD_POLICY(
    	object_schema => 'SCOTT',
    	object_name => 'TEST',
    	policy_name => 'chk3',
    	statement_types => 'insert,update,delete');
    END;
    

    这种方式激活的是FGA(fine granulate audit),可以对一个表进行非常精细的审计,审计结果存在 dba_fga_audit_trail这个表中。表结构如下:

    SQL> desc dba_fga_audit_trail
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     SESSION_ID                                NOT NULL NUMBER
     TIMESTAMP                                          DATE
     DB_USER                                            VARCHAR2(30)
     OS_USER                                            VARCHAR2(255)
     USERHOST                                           VARCHAR2(128)
     CLIENT_ID                                          VARCHAR2(64)
     ECONTEXT_ID                                        VARCHAR2(64)
     EXT_NAME                                           VARCHAR2(4000)
     OBJECT_SCHEMA                                      VARCHAR2(30)
     OBJECT_NAME                                        VARCHAR2(128)
     POLICY_NAME                                        VARCHAR2(30)
     SCN                                                NUMBER
     SQL_TEXT                                           NVARCHAR2(2000)
     SQL_BIND                                           NVARCHAR2(2000)
     COMMENT$TEXT                                       VARCHAR2(4000)
     STATEMENT_TYPE                                     VARCHAR2(7)
     EXTENDED_TIMESTAMP                                 TIMESTAMP(6) WITH TIME ZONE
     PROXY_SESSIONID                                    NUMBER
     GLOBAL_UID                                         VARCHAR2(32)
     INSTANCE_NUMBER                                    NUMBER
     OS_PROCESS                                         VARCHAR2(16)
     TRANSACTIONID                                      RAW(8)
     STATEMENTID                                        NUMBER
     ENTRYID                                            NUMBER
     DBID                                               NUMBER
    

    可以看到这里收集到的auditi信息其实已经非常丰富了。但是客户的需求里多了一条,需要client 机器上 client进程的pid。 但是现在的dba_fga_audit_trial这个表中并没有client pid这一列。所以我们需要自己获得。同时我们需要创建一个新的表来存放 audit 结果。

    具体过程是先创建 temp_audit表:

    SQL> desc temp_audit
     Name                                      Null?    Type
     ----------------------------------------- -------- ----------------------------
     TIMESTAMP                                          DATE
     DB_USER                                            VARCHAR2(30)
     OS_USER                                            VARCHAR2(30)
     USERHOST                                           VARCHAR2(30)
     CLIENTPID                                          VARCHAR2(10)
     OBJECT_SCHEMA                                      VARCHAR2(30)
     OBJECT_NAME                                        VARCHAR2(128)
     POLICY_NAME                                        VARCHAR2(30)
     SQL_TEXT                                           NVARCHAR2(2000)
     OS_PROCESS                                         VARCHAR2(16)

    这个先创建的用来存放audit 结果的表里面有一条clientpid是需要自己写SQL去查询的,其它的都可以直接从dba_fga_audit_trial中获得。 我们要考虑的是,怎么让目标表在发生变化的时候会把audit信息写入这个表。很显然,trigger是一个好办法。我们创建一个trigger在目标表上,当目标表被DML语句操作的时候,trigger就去读取dba_fga_audit_trial并且通过一系列SQL来写temp_audit这个表。

    我们首先写一个procedure 该procedure会读取dba_fga_audit_trial这个表并且通过一系列SQL得到client pid然后写入temp_audit。 然后我们再写一个trigger来调用这个procedure

    create or replace procedure pump_audit_CITOSADMIN
    as 
      cursor audit_cur is select * from dba_fga_audit_trail where OBJECT_SCHEMA='CITOSADMIN' and OBJECT_NAME='BERTH_APPLICATION' order by TIMESTAMP ;
      v_clientpid varchar2(12);
      v_my_audit_count number;
      v_count number;
    begin 
      select count(*) into v_my_audit_count from temp_audit where OBJECT_SCHEMA='CITOSADMIN' and OBJECT_NAME='BERTH_APPLICATION' ;
      v_count :=1;
      
      for record_name in audit_cur loop
        if v_count <= v_my_audit_count  
        then v_count := v_count+1;
        else     
          select b.process into v_clientpid from v$process a, v$session b where a.addr = b.paddr and a.spid=record_name.OS_PROCESS;
          insert into temp_audit(TIMESTAMP,DB_USER,OS_USER,USERHOST,CLIENTPID,OBJECT_SCHEMA,OBJECT_NAME,POLICY_NAME,SQL_TEXT,OS_PROCESS) values(record_name.TIMESTAMP,record_name.DB_USER,record_name.OS_USER,record_name.USERHOST,v_clientpid,record_name.OBJECT_SCHEMA,record_name.OBJECT_NAME,record_name.POLICY_NAME,record_name.SQL_TEXT,record_name.OS_PROCESS); 
        end if;
      end loop;
    end;
    

      

    create or replace trigger audit_obj_CITOSADMIN
      after insert or update or delete on CITOSADMIN.BERTH_APPLICATION
    begin
      pump_audit_CITOSADMIN;
    end;
  • 相关阅读:
    Project Euler 613 Pythagorean Ant(概率+积分)
    Codeforces Beta Round #24 D. Broken robot (打表找规律)
    Codeforces Beta Round #17 D. Notepad (数论 + 广义欧拉定理降幂)
    bzoj4916-神犇和蒟蒻
    bzoj4176-Lucas的数论
    bzoj2788-Festival
    bzoj2839-集合计数
    bzoj1853-大包子的幸运数字
    bzoj3622-已经没有什么好害怕的的了
    bzoj2669-局部极小值
  • 原文地址:https://www.cnblogs.com/kramer/p/3471225.html
Copyright © 2011-2022 走看看