oracle 10g - 监视大行删除

时间:2009-03-19 17:39:27

标签: sql database oracle monitoring

如何监控被删除的行(比如20行)? 考虑一下,我是一个dba并监控一个oracle数据库..如果有人删除超过20行,我必须得到一个警报..我应该避免触发因为它是昂贵的..还有其他方法吗?

我如何解析重做日志并捕获可能导致批量行删除的sql? 我的情况是,一旦批量行删除发生,DBA应该被暗示..除触发之外的任何其他方式?我一直在使用触发器,我正在寻找一种避免触发器的方法..

5 个答案:

答案 0 :(得分:3)

如果发生这种删除,你还希望做什么?除非你已经将已删除的行保存在某个地方(这需要触发器),否则你无法取回它们,甚至也不知道它们是什么。

如果删除行是一个问题并且可能需要恢复,请不要删除行:添加“已删除”列并将其值设置为UPDATE而不是DELETE(或添加触发器)。

或者,也许您可​​以找到解析重做日志的方法?我从来没有尝试过,但我想可以给予足够的努力。

就我个人而言,我想:

  1. 重新检查“需要”以了解删除,如果我无法改变,
  2. 克服了对触发器的恐惧。

答案 1 :(得分:1)

所以,回顾一下:你要求一种方法来监控,但没有使用触发器,因为在每个DELETE语句上执行该代码是“代价高昂”。

基本上,您正试图在没有监控开销的情况下找到监控方法。这是不可能的。触发器可以很好地完成这项工作,我非常怀疑你会注意到对要删除的行数进行简单检查会有任何性能差异。

答案 2 :(得分:0)

使用删除过程的过程并添加SQL%ROWCOUNT以监视已删除的行数。以下是Oracle文档中有关如何使用SQL%ROWCOUNT的示例:

CREATE TABLE employees_temp AS SELECT * FROM employees;

DECLARE
  mgr_no NUMBER(6) := 122;
BEGIN
  DELETE FROM employees_temp WHERE manager_id = mgr_no;
  DBMS_OUTPUT.PUT_LINE('Number of employees deleted: ' || TO_CHAR(SQL%ROWCOUNT));
END;
/

如果要使用FORALL语句,可以使用SQL%BULK_ROWCOUNT,方法与SQL%ROWCOUNT相同,这是Oracle文档中的另一个示例:

CREATE TABLE emp_temp AS SELECT * FROM employees;

DECLARE
   TYPE NumList IS TABLE OF NUMBER;
   depts NumList := NumList(30, 50, 60);
BEGIN

   FORALL j IN depts.FIRST..depts.LAST
      DELETE FROM emp_temp WHERE department_id = depts(j);

   -- How many rows were affected by each DELETE statement?
   FOR i IN depts.FIRST..depts.LAST
   LOOP
      DBMS_OUTPUT.PUT_LINE('Iteration #' || i || ' deleted ' || SQL%BULK_ROWCOUNT(i) || ' rows.');
   END LOOP;

END;
/

如果你真的有或想要避免触发器,我认为你应该这样做。

答案 3 :(得分:0)

如果您不想使用触发器,则选择dba是安装和设置数据库审计。通过审核功能,您可以跟踪谁做了什么,什么时间以及应该通知谁。如果删除时间段未超过撤消保留期,您还可以使用闪回功能获取已删除的行。在此之后,您可以使用logminer通过挖掘该时间段的日志来从存档/重做日志中恢复已删除的行。

答案 4 :(得分:0)

“我如何解析重做日志并捕获可能导致批量行删除的sql?我的方案是,只要发生批量行删除” 你在谈论什么类型的删除?

DELETE FROM表WHERE pk IN(1,.... 50)可以在一个语句执行中删除50行

FORALL i IN 1..50
 DELETE FROM table WHERE pk = i;

将有五十次执行,每次执行都会在一次交易中删除一行。

FOR i IN 1..50 LOOP
 DELETE FROM table WHERE pk = i;
 COMMIT;
END LOOP;

将执行50次执行,每次执行会在一次会话中删除50个事务中的单行。

您是否在单个语句,事务或会话中查找超过20行的删除? 采取最简单的选择。逻辑上,在每个DELETE语句之后,您需要查看已处理的行数,如果大于20,则创建审计记录。 从技术上讲,执行此类测试的方法是在表上创建一个AFTER DELETE行级触发器。任何替代方案都会产生与完成相同工作所需的完全相同的性能影响。 事务或会话级别限制类似,但您需要触发器来维护已删除的记录数(例如,在包级别变量中)。