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

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

DB宝 2023-08-02
340


题目部分

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地址

DROP TABLE T_IPADDRESS_LHR;

CREATE 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  
2
3SELECT A.HOST_ID || ': ' || A.HOST_ADDRESS HOST_IP1,
4
5       A.HOST_ADDRESS HOST_IP2,
6
7  A.HOST_ID HOST_NAME2
8
9        FROM V$DIAG_ALERT_EXT A
10
11       WHERE A.COMPONENT_ID = 'RDBMS'
12
13         AND UPPER(A.FILENAME) =
14
15             (SELECT UPPER(SUBSTR(D.VALUE, 1, (LENGTH(D.VALUE) - 5)) ||
16
17                           'ALERT' || SUBSTR(D.VALUE, -61) || 'LOG.XML')
18
19                FROM V$PARAMETER D
20
21               WHERE D.NAME = 'BACKGROUND_DUMP_DEST')
22
23         AND A.INDX =
24
25             (SELECT MAX(B.INDX)
26
27                FROM V$DIAG_ALERT_EXT B
28
29               WHERE B.COMPONENT_ID = 'RDBMS'
30
31                 AND UPPER(B.FILENAME) =
32
33                     (SELECT UPPER(SUBSTR(D.VALUE, 1, (LENGTH(D.VALUE) - 5)) ||
34
35                                   'ALERT' || SUBSTR(D.VALUE, -61) ||
36
37                                   'LOG.XML')
38
39                        FROM V$PARAMETER D
40
41                       WHERE D.NAME = 'BACKGROUND_DUMP_DEST'));
42
43/

复制

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

  1CREATE OR REPLACE PROCEDURE PH_IP_LHR AS
2
3
4
5  V_SQL VARCHAR2(4000);
6
7BEGIN
8
9
10
11  INSERT INTO T_IPADDRESS_LHR
12
13    (INST_ID, HOST_NAME)
14
15    SELECT V.INSTANCE_NUMBER, V.HOST_NAME FROM V$INSTANCE V;
16
17  COMMIT;
18
19
20
21  V_SQL := 'UPDATE T_IPADDRESS_LHR T
22
23     SET T.HOST_IP = UTL_INADDR.GET_HOST_ADDRESS
24
25   WHERE T.INST_ID = USERENV(''INSTANCE'')';
26
27
28
29  EXECUTE IMMEDIATE V_SQL;
30
31
32
33  COMMIT;
34
35
36
37EXCEPTION
38
39  WHEN OTHERS THEN
40
41
42
43    V_SQL := '
UPDATE T_IPADDRESS_LHR T
44
45       SET T.HOST_IP =
46
47           (SELECT V.HOST_IP2 FROM VH_IPADDRESS_LHR V)
48
49     WHERE T.INST_ID = USERENV(''INSTANCE'')';
50
51    EXECUTE IMMEDIATE V_SQL;
52
53    COMMIT;
54
55
56
57END PH_IP_LHR;
58
59/
60
614) 创建JOB来获取IP地址
62
63DECLARE
64
65  X NUMBER;
66
67BEGIN
68
69
70
71  FOR CUR IN (SELECT B.JOB
72
73                FROM DBA_JOBS B
74
75               WHERE B.WHAT = '
PH_IP_LHR;') LOOP
76
77
78
79    SYS.DBMS_IJOB.REMOVE(CUR.JOB);
80
81    COMMIT;
82
83  END LOOP;
84
85
86
87  FOR CUR IN (SELECT B.INST_ID FROM GV$INSTANCE B) LOOP
88
89
90
91    SYS.DBMS_JOB.SUBMIT(JOB       => X,
92
93                        WHAT      => 'PH_IP_LHR;',
94
95                        NEXT_DATE => SYSDATE+CUR.INST_ID/8640,
96
97                        INTERVAL  => 'NULL',
98
99                        NO_PARSE  => FALSE,
100
101                        INSTANCE  => CUR.INST_ID);
102
103    COMMIT;
104
105  END LOOP;
106
107END;
108
109/

复制

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

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

  1BEGIN
2
3  FOR CUR IN (SELECT V.INST_ID,
4
5                     V.INSTANCE_NAME,
6
7                     'INST_LHR_' || V.INST_ID SERVICE_NAME,
8
9                     'LHR_RAC' || V.INST_ID || '_JOB_CLASS' JOB_CLASS_NAME,
10
11                     'RAC_LHR_' || V.INST_ID JOB_NAME
12
13                FROM GV$INSTANCE V) LOOP
14
15    BEGIN
16
17      DBMS_SERVICE.STOP_SERVICE(SERVICE_NAME  => CUR.SERVICE_NAME,
18
19                                INSTANCE_NAME => CUR.INSTANCE_NAME);
20
21      DBMS_SERVICE.DELETE_SERVICE(SERVICE_NAME => CUR.SERVICE_NAME);
22
23    EXCEPTION
24
25      WHEN OTHERS THEN
26
27        NULL;
28
29    END;
30
31    BEGIN
32
33      DBMS_SCHEDULER.DROP_JOB_CLASS(JOB_CLASS_NAME => CUR.JOB_CLASS_NAME,
34
35                                    FORCE          => TRUE);
36
37    EXCEPTION
38
39      WHEN OTHERS THEN
40
41        NULL;
42
43    END;
44
45    BEGIN
46
47      DBMS_SCHEDULER.DROP_JOB(JOB_NAME => CUR.JOB_NAME, FORCE => TRUE);
48
49    EXCEPTION
50
51      WHEN OTHERS THEN
52
53        NULL;
54
55    END;
56
57  END LOOP;
58
59
60
61  FOR CUR IN (SELECT V.INST_ID,
62
63                     V.INSTANCE_NAME,
64
65                     'INST_LHR_' || V.INST_ID SERVICE_NAME,
66
67                     'LHR_RAC' || V.INST_ID || '_JOB_CLASS' JOB_CLASS_NAME,
68
69                     'RAC_LHR_' || V.INST_ID JOB_NAME
70
71                FROM GV$INSTANCE V) LOOP
72
73
74
75    DBMS_SERVICE.CREATE_SERVICE(SERVICE_NAME => CUR.SERVICE_NAME,
76
77                                NETWORK_NAME => CUR.SERVICE_NAME);
78
79    DBMS_SERVICE.START_SERVICE(SERVICE_NAME  => CUR.SERVICE_NAME,
80
81                               INSTANCE_NAME => CUR.INSTANCE_NAME);
82
83
84
85    DBMS_SCHEDULER.CREATE_JOB_CLASS(JOB_CLASS_NAME => CUR.JOB_CLASS_NAME,
86
87                                    SERVICE        => CUR.SERVICE_NAME);
88
89
90
91    DBMS_SCHEDULER.CREATE_JOB(JOB_NAME    => 'RAC_LHR_' || CUR.INST_ID,
92
93                              JOB_TYPE        => 'STORED_PROCEDURE',
94
95                              JOB_ACTION      => 'PH_IP_LHR',
96
97                              REPEAT_INTERVAL => NULL, --'FREQ=MINUTELY;INTERVAL=1'
98
99                              JOB_CLASS       => CUR.JOB_CLASS_NAME,
100
101                              END_DATE        => NULL,
102
103                              ENABLED         => TRUE);
104
105
106
107  END LOOP;
108
109END;
110
111/

复制




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

评论