Seiten

Dienstag, 25. Dezember 2012

Jobs in einer RAC-Installation an einen bestimmten Knoten binden

Es ist eigentlich ganz einfach, Jobs an einen bestimmten RAC-Knoten zu binden. Das einzige was man benötigt ist ein entsprechend konfigurierter Service und eine an diesen gebundene Job-Klasse.
Dem oder den Jobs weist man dann nur noch die Job-Klasse zu.
Fertig.

1. Service anlegen

Services legt man mit  dem DBCA oder srvctl an. Ich bevorzuge srvctl:
# Service auf einem Knoten anlegen 
srvctl add service -d RACDB -s JOB_SERVICE -r "RACDB1"

# Starten und stoppen des Service
srvctl start service -d RACDB -s JOB_SERVICE 
srvctl stop service -d RACDB -s JOB_SERVICE

# Disablen and enablen von Services.
srvctl disable service -d RACDB -s JOB_SERVICE
srvctl enable service -d RACDB -s JOB_SERVICE

# Möchte man den Service entfernen, dann mit remove:
srvctl remove service -d RACDB -s JOB_SERVICE

# Der Servicestatus:
srvctl status service -d RACDB -s JOB_SERVICE -v
Unter bestimmten Umständen zickt srvctl beim anlegen von Services. Beinhaltet die Domain der DB zum Beispiel ein "-" (minus), dann bemeckert srvctl das mit einem nichtssagenden PRCD-1223:
srvctl add service -d RACDB -s JOB_SERVICE -r "RACDB1"
PRCD-1223 : Der Servicename JOB_SERVICE enthält unzulässige Zeichen -
Abhilfe schafft die Umbenennung der Domain in der DB. Angenommen die Domain lautet "meinefirma-deutschland.de", macht man aus dem "-" einfach einen Punkt, oder was einem sonst gefällt.
srvctl modify database -m meinefirma.deutschland.de -d RACDB
Anschließend legt man den Service an und benennt die Domain wieder um.
srvctl add service -d RACDB -s JOB_SERVICE -r "RACDB1"
srvctl modify database -m meinefirma-deutschland.de -d RACDB

2. Job-Class anlegen

BEGIN
  DBMS_SCHEDULER.create_job_class (
    job_class_name => 'NODE1_JOB_CLASS',
    service        => 'JOB_SERVICE');
END;
/

3. Jobs eine Job-Klasse zuweisen

Jetzt kann man neue Jobs direkt einer Job-Klasse zuweisen oder existierende Jobs entsprechend ändern

3.a) Einen neuen Job mit Jobklasse anlegen

Beim anlegen eines Jobs kann man ihm mit dem Parameter JOB_CLASS gleich die Job-Klasse zuweisen.
Ohne Verwendung dieses Parameters, erfolgt die Zuweisung des Defaultwertes:
BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'TEST_JOB',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'BEGIN ... END;',
    job_class       => 'NODE1_JOB_CLASS',
    repeat_interval => 'FREQ=DAILY',
    enabled         => TRUE,
    comments        => 'Job mit Zuordnung zu einer Job-Klasse');
END;
/

3.b) Zuordnung einer Job-Klasse zu einem existierenden Job

Einfach:
BEGIN
  DBMS_SCHEDULER.set_attribute (
    name      => 'TEST_JOB',
    attribute => 'job_class',
    value     => 'NODE1_JOB_CLASS');
END;
/

4. Sonstiges

Jobs abfragen

SELECT owner, job_name, job_class, enabled 
FROM dba_scheduler_jobs;

Test: Führt der RAC den Job tatsächlich nur auf Node1 aus?

Wenn man testen möchte, ob die Servicezuweisung wirklich funktioniert, kann man wie folgt vorgehen.
Man legt per CTAS eine Testtabelle an:
CREATe TABLE job_test AS 
SELECT sysdate time, instance_name, host_name 
FROM v$instance;
Dann legt man einen Job an, der sekündlich sysdate, den Instanz- und Hostnamen in die Testtabelle schreibt:
BEGIN
  DBMS_SCHEDULER.create_job (
    job_name        => 'TEST_JOB',
    job_type        => 'PLSQL_BLOCK',
    job_action      => 'INSERT INTO job_test SELECT sysdate time, instance_name, host_name FROM v$instance;commit;',
    job_class       => 'NODE1_JOB_CLASS',
    start_date      => TO_TIMESTAMP_TZ('02/01/2012 13:45:00','dd/mm/yyyy hh24:mi:ss'),
    repeat_interval => 'FREQ=SECONDLY',
    end_date        => TO_TIMESTAMP_TZ('02/01/2013 14:00:00','dd/mm/yyyy hh24:mi:ss'),
    enabled         => TRUE,
    comments        => 'Job mit Zuordnung zu einer Job-Klasse');
END;
/
Die Abfrage zur Überprüfung sollte dann natürlich nur die eine beteiligte Instanz hervorzaubern:
SELECT * FROM job_test ORDER BY 1 DESC;

Was passiert, wenn der Service gedropt wird?

Wenn ein Service gelöscht wird, auf den Job-Klassen verweisen, wird automatisch die Default-Job-klasse gezogen.

Beispiel für die Nutzung von Services

Auf einer Oracle-RAC-DB mit 4 Knoten laufen eine Client-Server-Anwendung, ein Webportal und mehrere über Webservices realisierte Schnittstellen zu anderen Anwendungen.
Die Anforderungen der 3 auf die DB zugreifenden Systeme unterscheiden sich stark und sollen voneinander getrennt und optimiert arbeiten. 
# 3 Services anlegen
srvctl add service -d RACDB -s CLIENT_SERVICE -r RACDB1 -a "RACDB1,RACDB4"
srvctl add service -d RACDB -s WWW_SERVICE -r RACDB2,RACDB3 -a "RACDB2,RACDB3,RACDB4"
srvctl add service -d RACDB -s BATCH_SERVICE -r RACDB4 -a "RACDB1,RACDB4"
Jetzt müssen die Clients, das Webportal und die Web-/Batchservices nur noch entsprechend auf die Services zugreifen.
Das konfiguriert man z.B. in den jeweiligen tnsnames.ora.
Der Clientservice kann dann auf allen 4 Knoten, wird aber bevorzugt auf dem 1er laufen.
Das Webportal wird bevorzugt auf 2 und 3 ausgeführt, kennt aber außerdem noch den 4er.
Die Schnittstellen laufen wiederum auf dem 4er und notfalls dem 1er.

Keine Kommentare:

Kommentar veröffentlichen