设计Oracle数据库上的作业监视

时间:2018-02-07 12:24:06

标签: oracle database-design monitoring jobs database-link

我有几个Oracle数据库,我的内部应用程序正在运行。这些应用程序同时使用dba_jobsdba_scheduler_jobs

我想编写监控功能:check_my_jobs,Nagios会定期调用它来检查我的工作是否一切正常。 (它们正在运行吗?它是否已损坏?next_run_date是否已延迟?依此类推)

解决方案:由于我必须监控不同数据库上的作业,因此有两种方法可以实现解决方案:

  1. 仅在一个数据库上创建监控功能和配置表,该数据库将使用数据库链接检查每个数据库上的作业。

    专业人士:集中功能,易于维护。
    缺点:我必须使用数据库链接进行检查。

  2. 在我想要检查作业的每个数据库上创建监控功能和配置表。

    专业人士:我不必使用数据库链接
    缺点:每个数据库上都有重复的监控代码

  3. 哪种解决方案更好?

1 个答案:

答案 0 :(得分:2)

我选择#1选项 - 使用数据库链接的集中功能。

数据库链接的名声不好。其中一个主要原因是有太多人使用 public 数据库链接,任何连接到数据库的人都可以使用该链接。这显然是一场安全噩梦,但这不是默认设置,很容易避免陷阱。

数据库链接的其他一些问题:

  1. 对于数百万行的大量插入,它们表现不佳。另一方面,他们在许多小型SELECT或INSERT中表现出色。我经常在10年前的硬件上同时打开数百个链接并获取数据,而且效果很好。
  2. 他们使执行计划更难以排除故障。
  3. 并非所有数据类型都是本机支持的。这在12.2中更好,但在早期版本中,您需要使用INSERT将数据类型(如CLOB)移动到表中,然后从这些表中读取。
  4. 对于DDL,您需要使用DBMS_UTILITY.EXEC_DDL_STATEMENT@LINK_NAME('create ...');确保只在那里使用DDL。其他类型的命令将无声地失败。
  5. 链接可能会在极少数情况下无限期挂起,例如数据库存在归档错误或保证还原点已满。 (这实际上是伪装的祝福 - 像Oracle企业管理器这样的许多工具都不会捕获这些问题。您可能希望让后台作业检查运行时间超过X分钟的数据库链接查询。)
  6. 链接不应该是硬编码的,否则它们可能会使包无效。但这可能无关紧要 - 您可能想要遍历数据库列表并使用动态SQL。如果链接不存在,那么创建一个新链接非常容易。这是一个例子:

    declare
        v_result varchar2(4000);
    begin
        --Loop through a configuration table of links.
        for links in
        (
            select database_name, db_link
            from dbs_to_monitor
            left join user_db_links
                on dbs_to_monitor.database_name = user_db_links.db_link
            order by database_name
        ) loop
            --Run the query if the link exists.
            if links.db_link is not null then
                begin
                    --Note the user of REPLACE and the alternative quoting mechanism, q'[...]';
                    --This looks a bit silly with this small example, but in a real-life query
                    --it avoids concatenation hell and makes the query much easier to read. 
                    execute immediate replace(q'[
                        select dummy from dual@#DB_LINK#
                    ]',
                    '#DB_LINK#', links.db_link)
                    into v_result;
    
                    dbms_output.put_line('Result: '||v_result);
                --Catch errors if the links are broken or some other error happens.
                exception when others then
                    dbms_output.put_line('Error with '||links.db_link||': '||sqlerrm);
                end;
            --Error if the link was not created.
            --You will have to run:
            --create database link LINK_NAME connect to USERNAME identified by "PASSWORD" using 'TNS_STRING'; 
            else
                dbms_output.put_line('ERROR - '||links.db_link||' does not exist!');
            end if;
        end loop;
    end;
    /
    
  7. 尽管如此,数据库链接非常棒,因为您可以在一个数据库中完成PL / SQL中的所有操作。使用单一语言,您可以创建无代理监控解决方案,而无需担心安装和修复代理。

    作为一个例子,我构建了开源程序Method5来使用数据库链接完成所有事情。安装该程序后,您可以像运行select * from table(m5('select * from dba_jobs'));一样收集数百个数据库的结果。该程序可能对您的方案有些过分,但它表明数据库链接是完整监控解决方案所需的全部内容。