oracle 10g - 监控大行删除

Posted

技术标签:

【中文标题】oracle 10g - 监控大行删除【英文标题】:oracle 10g - Monitor large row deletions 【发布时间】:2009-03-19 17:39:27 【问题描述】:

我如何监控被删除的行(比如 20 行)? 考虑一下,我是一名 dba,正在监视一个 oracle 数据库。如果有人删除了超过 20 行,我必须收到警报。我应该避免使用触发器,因为它很昂贵。还有其他方法吗?

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

【问题讨论】:

您的团队中是否有人实际测量过使用触发器执行此操作的成本?什么是触发代码,它是如何测量的? 你害怕触发因素背后的逻辑是什么? 我正在寻找一种避免触发器的方法.. 在我的应用程序中触发成本很高.. 【参考方案1】:

如果发生这样的删除,您希望做什么?除非您已将已删除的行保存在某处(这需要触发器),否则您无法恢复它们,甚至无法知道它们是什么。

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

或者,也许您可​​以找到解析重做日志的方法?我从未尝试过,但我想只要付出足够的努力,它是可能的。

就个人而言,我认为我会:

    重新审视了解删除的“必要性”,如果我无法更改, 克服我对触发器的恐惧。

【讨论】:

当然,您可以找回它们——Oracle 的闪回技术可以让您做到这一点。 好悲痛。我怎么错过了?更重要的是,提问者,他说他是一名 DBA(我肯定已经有十多年没有做过了)怎么也不知道呢?我责怪学校... ;-)【参考方案2】:

因此,回顾一下:您正在寻求一种监控方式,但不使用触发器,因为在每个 DELETE 语句上执行该代码“代价高昂”。

基本上,您正在尝试找到一种无需监控开销的监控方法。那是不可能的。触发器可以很好地完成这项工作,我非常怀疑您是否会注意到简单检查正在删除的行数的任何性能差异。

【讨论】:

【参考方案3】:

为您的删除过程使用一个过程并添加一个 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%ROWCOUNT 一样使用 SQL%BULK_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;
/

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

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

“我如何解析重做日志并捕获可能导致批量行删除的 sql?我的情况是,一旦发生批量行删除” 你在说什么样的删除?

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

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

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

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

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

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

【讨论】:

以上是关于oracle 10g - 监控大行删除的主要内容,如果未能解决你的问题,请参考以下文章

oracle 索引监控

oracle_session_process监控

网络分流器-IDC如何监控?流量如何采集?

部署了zabbix服务器监控以后,咱么修改磁盘空间报警的值,默认貌似是磁盘空间小于10%就报警,想修改为10G

oracle 10g 删除用户时提示ORA-00604 :递归SQL级别 1

oracle 10g 系统数据库USERS01.DBF增长过大,能不能删除重建?