Wenn man das Statspack auf einem RAC benutzen will, kann es laut Jonathan Lewis dazu kommen, dass sich die einzelnen Instanzen beim Zugriff auf die DB gegenseitig locken.
"Now there’s no reason why Statspack should
lock up a RAC cluster – in principle. But this was an 8-node cluster and
if you set up the automatic job to take snapshots by running the
default spauto.sql script all eight nodes
could start running every hour on the hour – so they would all be
fighting constantly for every block of every table and index in the Statspack
schema. (I’m exaggerating for effect, of course, but not by much). You
might not notice the global cache contention in a 2-node cluster but
eight nodes could, indeed, “lock up the system” at this point."
Sein Artikel bezieht sich zwar auf die 10g, aber es sieht so aus, als könnte es dieses Risiko in der 11g und höher weiterhin geben.
Auch ist RAC mit 2 Nodes wohl nicht gefährdet. Ich habe trotzdem ein wenig weiter gegraben. Hier http://www.oracle-class.com/?p=2384 ist ein guter Artikel, in dem beschrieben wird, wie man das Statspack auf einem 4-Node-RAC ausführen lässt. Die Anleitung bezieht sich ebenfalls auf Jonathan Lewis und nutzt sehr anschaulich DBMS_SCHEDULER und Services um die einzelnen Nodes gezielt anzusprechen.
Die Skripte lassen sich - geringfügig angepasst - so nutzen.
Posts mit dem Label dbms_scheduler werden angezeigt. Alle Posts anzeigen
Posts mit dem Label dbms_scheduler werden angezeigt. Alle Posts anzeigen
Dienstag, 8. Juli 2014
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.
Ohne Verwendung dieses Parameters, erfolgt die Zuweisung des Defaultwertes:
Man legt per CTAS eine Testtabelle an:
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.
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 -vUnter 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 RACDBAnschließ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 ändern3.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.
Samstag, 22. Dezember 2012
dbms_scheduler mit EXECUTABLE unter Windows
Will man unter Windows datenbankgesteuert regelmäßig Dateioperationen im Netzwerk ausführen, muss man einige Hürden überwinden.
An diesem Beispiel beschreibe ich die notwendigen Schritte:
Aus der Oracledatenbank (11.2.0.3) wird täglich um 20:00Uhr eine Batchdatei (d:\skripte\backup.bat) gestartet, die eine Datei inkl. Tagesdatum ins Firmennetz sichern soll.
Der Inhalt der backup.bat:
Diese Argumente setzt man mit DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(). Das Logging setzt man mit DBMS_SCHEDULER.SET_ATTRIBUTE. Diese Loglevel gibt es:
Zuletzt muss der Job enabled werden. Standardmäßig sind die Jobs disabled und werden damit nicht ausgeführt.
Was ist zu beachten? Der Prozess, der die Batchdatei startet, muss unter einem Konto laufen, dass Schreibrechte ins Netz hat.
Nach einer Standardinstallation werden die Windowsdienste unter dem Systemkonto (Local System) ausgeführt. Der Schedulerservice selbst ist sogar disabled:
Den Service muss man enablen und einem Konto zuweisen, das Schreibrechte ins Netzwerk besitzt - hier ora_dba:
Jetzt sollte der Job wie erwartet funktionieren. Das Log kann man mit diesem Select abrufen:
An diesem Beispiel beschreibe ich die notwendigen Schritte:
Aus der Oracledatenbank (11.2.0.3) wird täglich um 20:00Uhr eine Batchdatei (d:\skripte\backup.bat) gestartet, die eine Datei inkl. Tagesdatum ins Firmennetz sichern soll.
Der Inhalt der backup.bat:
set jahr=%date:~-4% set monat=%date:~-7,2% set tag=%date:~-10,2% copy D:\oradata\orcl\backup.zip \\192.168.2.100\bckp\%jahr%%monat%%tag%_backup.zipDas Skript um den Scheduler-Job zu erzeugen, sieht so aus:
BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'JOB_COPY_BACKUP' ,repeat_interval => 'FREQ=DAILY;BYHOUR=20' ,job_class => 'DEFAULT_JOB_CLASS' ,job_type => 'EXECUTABLE' ,NUMBER_OF_ARGUMENTS => 2 ,job_action => 'c:\windows\system32\cmd.exe' ,comments => 'Job startet das Backup.' ); END; /Das Grundgerüst steht damit. Weil man die Batchdatei nicht direkt aufrufen kann, muss man sie als Argument an die Commandshell inkl. Schalter "/C" übergeben. Das sähe dann in etwa so aus: "c:\windows\system32\cmd.exe /c d:\skripte\backup.bat > nul"
Diese Argumente setzt man mit DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(). Das Logging setzt man mit DBMS_SCHEDULER.SET_ATTRIBUTE. Diese Loglevel gibt es:
- DBMS_SCHEDULER.LOGGING_OFF,
- DBMS_SCHEDULER.LOGGING_RUNS,
- DBMS_SCHEDULER.LOGGING_FULL
Zuletzt muss der Job enabled werden. Standardmäßig sind die Jobs disabled und werden damit nicht ausgeführt.
BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE('JOB_COPY_BACKUP',1,'/c'); DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE( 'JOB_COPY_BACKUP',2,'d:\skripte\backup.bat > nul'); DBMS_SCHEDULER.SET_ATTRIBUTE( name => 'JOB_COPY_BACKUP' ,attribute => 'LOGGING_LEVEL' ,value => DBMS_SCHEDULER.LOGGING_RUNS); DBMS_SCHEDULER.SET_ATTRIBUTE( name => 'JOB_COPY_BACKUP' ,attribute => 'AUTO_DROP' ,value => FALSE); DBMS_SCHEDULER.ENABLE('JOB_COPY_BACKUP'); END; /Bei einem "normalen" Job ohne Netzwerkugriff wäre man jetzt fertig. In diesem Fall würde der Job in einer Fehlermeldung enden.
Was ist zu beachten? Der Prozess, der die Batchdatei startet, muss unter einem Konto laufen, dass Schreibrechte ins Netz hat.
Nach einer Standardinstallation werden die Windowsdienste unter dem Systemkonto (Local System) ausgeführt. Der Schedulerservice selbst ist sogar disabled:
Den Service muss man enablen und einem Konto zuweisen, das Schreibrechte ins Netzwerk besitzt - hier ora_dba:
Jetzt sollte der Job wie erwartet funktionieren. Das Log kann man mit diesem Select abrufen:
select * from dba_scheduler_job_log where job_name = 'JOB_COPY_BACKUP'Was gibt es sonst noch?
- Man kann Jobs auch über "credentials" mit Username und Passwort starten. Das habe ich noch nicht ausprobiert.
- Wenn man einen "EXECUTABLE-Job" in einer RAC-Umgebung anlegt, gibt es das Problem, dass der Scheduler-Job auf jedem Knoten ausgeführt werden kann. Dann muss man entweder dafür sorgen, dass die Files (Programme, Batch-Dateien...), auch tatsächlich für jeden Knoten auffindbar sind - Oder: Man sorgt dafür, dass der Scheduler-Job nur auf einem bestimmten Knoten läuft. Dazu später. (Stichwort: job_class)
- Möchte man über Probleme oder auch nur die reine Jobausführung per Email benachrichtigt werden, kann man sich seit 11g bequem per eingebauter "email_notification" benachrichtigen lassen.
- Außerdem bietet das Scheduler-Package auch die Möglichkeit, per Window die Ausführungszeiten zu steuern.
Abonnieren
Posts (Atom)