暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

RAC中如何指定JOB的运行实例?

DB宝 2019-03-31
1605


题目部分

RAC中如何指定JOB的运行实例?


     

答案部分


RAC中,可以让JOB在某个指定的实例上运行。对于DBMS_JOBDBMS_SCHEDULER来说,它们的指定方法不同

1DBMS_JOB,在执行SYS.DBMS_JOB.SUBMIT包创建JOB的时候,可以指定INSTANCE参数,该参数指定了JOB运行的实例RAC环境中,采用DBMS_JOB包可以指定JOB运行时候的实例

示例代码如下所示,该例子展示了获取RAC数据库的IP地址并记录到临时表T_IPADDRESS_LHR中,例子很经典,希望读者可以理解。

1) 创建临时表用于记录RAC数据库的IP地址

1DROP TABLE T_IPADDRESS_LHR;
2CREATE TABLE T_IPADDRESS_LHR(INST_ID NUMBER, HOST_NAME VARCHAR2(255), HOST_IP  VARCHAR2(255) );

复制

2) 创建视图VH_IPADDRESS_LHR用于从V$DIAG_ALERT_EXT中获取IP地址

 1CREATE OR REPLACE VIEW VH_IPADDRESS_LHR AS  
2SELECT A.HOST_ID || ': ' || A.HOST_ADDRESS HOST_IP1,
3       A.HOST_ADDRESS HOST_IP2,
4  A.HOST_ID HOST_NAME2
5        FROM V$DIAG_ALERT_EXT A
6       WHERE A.COMPONENT_ID = 'RDBMS'
7         AND UPPER(A.FILENAME) =
8             (SELECT UPPER(SUBSTR(D.VALUE, 1, (LENGTH(D.VALUE) - 5)) ||
9                           'ALERT' || SUBSTR(D.VALUE, -61) || 'LOG.XML')
10                FROM V$PARAMETER D
11               WHERE D.NAME = 'BACKGROUND_DUMP_DEST')
12         AND A.INDX =
13             (SELECT MAX(B.INDX)
14                FROM V$DIAG_ALERT_EXT B
15               WHERE B.COMPONENT_ID = 'RDBMS'
16                 AND UPPER(B.FILENAME) =
17                     (SELECT UPPER(SUBSTR(D.VALUE, 1, (LENGTH(D.VALUE) - 5)) ||
18                                   'ALERT' || SUBSTR(D.VALUE, -61) ||
19                                   'LOG.XML')
20                        FROM V$PARAMETER D
21                       WHERE D.NAME = 'BACKGROUND_DUMP_DEST'));
22/

复制

3) 创建存储过程用于在指定的实例上运行程序,首先从函数UTL_INADDR.GET_HOST_ADDRESS中获取,若是系统没有该包,则从视图VH_IPADDRESS_LHR中获取IP地址

 1CREATE OR REPLACE PROCEDURE PH_IP_LHR AS
2  V_SQL VARCHAR2(4000);
3BEGIN
4  INSERT INTO T_IPADDRESS_LHR
5    (INST_ID, HOST_NAME)
6    SELECT V.INSTANCE_NUMBER, V.HOST_NAME FROM V$INSTANCE V;
7  COMMIT;
8  V_SQL := 'UPDATE T_IPADDRESS_LHR T
9     SET T.HOST_IP = UTL_INADDR.GET_HOST_ADDRESS
10   WHERE T.INST_ID = USERENV(''INSTANCE'')';
11  EXECUTE IMMEDIATE V_SQL;
12  COMMIT;
13EXCEPTION
14  WHEN OTHERS THEN
15    V_SQL := '
UPDATE T_IPADDRESS_LHR T
16       SET T.HOST_IP =
17           (SELECT V.HOST_IP2 FROM VH_IPADDRESS_LHR V)
18     WHERE T.INST_ID = USERENV(''INSTANCE'')';
19    EXECUTE IMMEDIATE V_SQL;
20    COMMIT;
21END PH_IP_LHR;
22/
23


复制

4) 创建JOB来获取IP地址

 1DECLARE
2  X NUMBER;
3BEGIN
4  FOR CUR IN (SELECT B.JOB
5                FROM DBA_JOBS B
6               WHERE B.WHAT = 'PH_IP_LHR;'LOOP
7    SYS.DBMS_IJOB.REMOVE(CUR.JOB);
8    COMMIT;
9  END LOOP;
10  FOR CUR IN (SELECT B.INST_ID FROM GV$INSTANCE B) LOOP
11    SYS.DBMS_JOB.SUBMIT(JOB       => X,
12                        WHAT      => 'PH_IP_LHR;',
13                        NEXT_DATE => SYSDATE+CUR.INST_ID/8640,
14                        INTERVAL  => 'NULL',
15                        NO_PARSE  => FALSE,
16                        INSTANCE  => CUR.INST_ID);
17    COMMIT;
18  END LOOP;
19END;
20/

复制


(2)DBMS_SCHEDULER下指定实例运行JOB稍微有点复杂,首先创建SERVICE,再创建JOB_CLASS,最后创建JOB才可以,具体过程可以参考如下案例的代码。

该例子和上面的DBMS_JOB例子一样展示了获取集群数据库的IP地址并记录到临时表T_IPADDRESS_LHR中,例子的前3步和上面的例子一样,不再赘述,接下来就是创建SERVICEJOB_CLASS,最后是创建JOB的过程。

 1BEGIN
2  FOR CUR IN (SELECT V.INST_ID,
3                     V.INSTANCE_NAME,
4                     'INST_LHR_' || V.INST_ID SERVICE_NAME,
5                     'LHR_RAC' || V.INST_ID || '_JOB_CLASS' JOB_CLASS_NAME,
6                     'RAC_LHR_' || V.INST_ID JOB_NAME
7                FROM GV$INSTANCE V) LOOP
8    BEGIN
9      DBMS_SERVICE.STOP_SERVICE(SERVICE_NAME  => CUR.SERVICE_NAME,
10                                INSTANCE_NAME => CUR.INSTANCE_NAME);
11      DBMS_SERVICE.DELETE_SERVICE(SERVICE_NAME => CUR.SERVICE_NAME);
12    EXCEPTION
13      WHEN OTHERS THEN
14        NULL;
15    END;
16    BEGIN
17      DBMS_SCHEDULER.DROP_JOB_CLASS(JOB_CLASS_NAME => CUR.JOB_CLASS_NAME,
18                                    FORCE          => TRUE);
19    EXCEPTION
20      WHEN OTHERS THEN
21        NULL;
22    END;
23    BEGIN
24      DBMS_SCHEDULER.DROP_JOB(JOB_NAME => CUR.JOB_NAME, FORCE => TRUE);
25    EXCEPTION
26      WHEN OTHERS THEN
27        NULL;
28    END;
29  END LOOP;
30  FOR CUR IN (SELECT V.INST_ID,
31                     V.INSTANCE_NAME,
32                     'INST_LHR_' || V.INST_ID SERVICE_NAME,
33                     'LHR_RAC' || V.INST_ID || '_JOB_CLASS' JOB_CLASS_NAME,
34                     'RAC_LHR_' || V.INST_ID JOB_NAME
35                FROM GV$INSTANCE V) LOOP
36    DBMS_SERVICE.CREATE_SERVICE(SERVICE_NAME => CUR.SERVICE_NAME,
37                                NETWORK_NAME => CUR.SERVICE_NAME);
38    DBMS_SERVICE.START_SERVICE(SERVICE_NAME  => CUR.SERVICE_NAME,
39                               INSTANCE_NAME => CUR.INSTANCE_NAME);
40    DBMS_SCHEDULER.CREATE_JOB_CLASS(JOB_CLASS_NAME => CUR.JOB_CLASS_NAME,
41                                    SERVICE        => CUR.SERVICE_NAME);
42    DBMS_SCHEDULER.CREATE_JOB(JOB_NAME    => 'RAC_LHR_' || CUR.INST_ID,
43                              JOB_TYPE        => 'STORED_PROCEDURE',
44                              JOB_ACTION      => 'PH_IP_LHR',
45                              REPEAT_INTERVAL => NULL, --'FREQ=MINUTELY;INTERVAL=1'
46                              JOB_CLASS       => CUR.JOB_CLASS_NAME,
47                              END_DATE        => NULL,
48                              ENABLED         => TRUE);
49  END LOOP;
50END;
51/

复制



& 说明:

有关具体的操作过程可以参考我的BLOGhttp://blog.itpub.net/26736162/viewspace-2072635/


本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。



---------------优质麦课------------

 详细内容可以添加麦老师微信或QQ私聊。



About Me:小麦苗

 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 作者博客地址:http://blog.itpub.net/26736162/abstract/1/

 本系列题目来源于作者的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

 版权所有,欢迎分享本文,转载请保留出处

 QQ:646634621  QQ群:618766405

 提供OCP、OCM和高可用部分最实用的技能培训

● 题目解答若有不当之处,还望各位朋友批评指正,共同进步

长按下图识别二维码或微信扫描下图二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,学习最实用的数据库技术。


最后修改时间:2020-01-13 22:17:37
文章转载自DB宝,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论