【问题标题】:Need logs for the data entered in oracle在 oracle 中输入的数据需要日志
【发布时间】:2021-08-24 12:48:58
【问题描述】:

我已经在 oracle 数据库中的一个表中输入了数据

表名是 TABLE1,它有 3 列,即 (ROLL_NO, NAME, AGE)

CREATE TABLE TABLE1
(
   ROLL_NO NUMBER NOT NULL,
   NAME VARCHAR2(10),
   AGE NUMBER
);

INSERT INTO TABLE1 VALUES(1, 'BOB', 20);
INSERT INTO TABLE1 VALUES(2, 'TOM', 21);
INSERT INTO TABLE1 VALUES(3, 'SAM', 22);

我只想要在 oracle 中输入的数据的日志。如何获取输入这些数据的日志

【问题讨论】:

  • 您在寻找什么“日志”?您可以在插入之前对表启用审计,然后查看审计数据。您可以使用 LogMiner 挖掘 Oracle 为插入语句生成的重做日志(假设您保留了执行此检查所需的所有重做日志)。您可以在表上创建一个触发器,将修改记录到单独的历史表中。这完全取决于您真正想要解决的问题。
  • 我只需要输入这些数据的人、时间和时间等日志。
  • 在这种情况下,“谁”是执行 insert 的 Oracle 用户吗?通常,人们正在寻找 Oracle 不知道的应用程序用户。在玩具环境中进行插入后,您是否需要立即使用它?如果是这样,LogMiner 是相当合理的。或者您是否需要多年后在生产环境中获取这些信息?在这种情况下,LogMiner 将过于繁琐。你可以添加列来跟踪这个到表中吗?你能创建一个单独的历史表吗?
  • 在这种情况下,“谁”是执行插入的 Oracle 用户吗?通常,人们正在寻找 Oracle 不知道的应用程序用户。您在寻找今天的信息吗?还是从一周前开始的?我假设 prod 环境处于archivelog 模式。您是否有从输入数据时起的存档日志?
  • Oracle 默认不会在数据级别进行审计。这是因为审计是一种开销,审计跟踪越细,开销就越高。因此,这是我们需要启用自己的东西。当然,正如您正在发现的那样,没有积极的审计跟踪会带来自己的成本。

标签: oracle logging plsql oracle11g


【解决方案1】:

您可以创建一个额外的表来保留那些 DML 日志,例如

CREATE TABLE log_table1
(
   id          NUMBER,
   dml_type    VARCHAR2(1),
   roll_no     NUMBER,
   name        VARCHAR2(10),
   age         NUMBER,
   client_info VARCHAR2(64), 
   osuser      VARCHAR2(128), 
   module      VARCHAR2(64),
   machine     VARCHAR2(64),
   time        DATE 
);
/

和一个数据库触发器,用于填充该表以及为每个记录生成标识值的序列,例如

CREATE SEQUENCE seq_table1;
/

然后

CREATE OR REPLACE TRIGGER trg_log_table1
AFTER INSERT OR UPDATE OR DELETE ON table1
FOR EACH ROW
DECLARE
  v_dml_type     VARCHAR2(1):='I';
  v_client_info  v$session.client_info%TYPE;
  v_osuser       v$session.osuser%TYPE;
  v_module       v$session.module%TYPE;
  v_machine      v$session.machine%TYPE;
BEGIN
    SELECT client_info, osuser, module, machine
      INTO v_client_info, v_osuser, v_module, v_machine
      FROM v$session
     WHERE sid = sys_context('USERENV','SID');

  IF inserting OR updating THEN
    IF updating THEN v_dml_type := 'U'; END IF;
    INSERT INTO log_table1
    VALUES(seq_table1.nextval,v_dml_type,:new.roll_no,:new.name,:new.age,v_client_info, v_osuser, v_module, v_machine,SYSDATE);
  ELSIF deleting THEN
    v_dml_type := 'D';
    INSERT INTO log_table1
    VALUES(seq_table1.nextval,v_dml_type,:old.roll_no,:old.name,:old.age,v_client_info, v_osuser, v_module, v_machine,SYSDATE);
  END IF;
END;
/

如果某些行的 client_infomodule 得到 null 值,可能需要调用这些过程

dbms_application_info.set_module(i_module,i_action);
dbms_application_info.set_client_info(i_client);

从您访问数据库的应用程序以填充这些列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2016-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多