Benutzer-Werkzeuge

Webseiten-Werkzeuge


dba:oracle_scheduler_log_pflege

DBMS_SCHEDULER Job Log Lösch-Verhalten - Löschen optimieren

wohl ab min. 11g - getestet 12.2 und 19c

Aufgabe:

Der Oracle Scheduler loggt alle Läufe der Jobs in den Tabellen sys.scheduler$_event_log und sys.scheduler$_job_run_details. In einer Datenbank sind nun schon mehr als 4000 Tage an Log Informationen aufgelaufen.

Warum also löscht der automatische Job der Datenbank diese Daten nicht?

Aufgefallen ist der Fehler weil Abfragen auf die DBA Views für die Job Logs recht lange Laufzeiten (deutlich in 10sec Bereich) aufweisen.

Lösung:

Tägliche läuft im normal Fall ein Job mit DBMS_SCHEDULER.PURGE_LOG() der dieses Log aufräumt indem alles älter als der Parameter LOG_HISTORY ( auslesen mit DBA_SCHEDULER_GLOBAL_ATTRIBUTE ), im Default steht dieser Wert auf den Wert 30.

Allerdings kann dieser Parameter auf JOB Klassen Ebene (DBA_SCHEDULER_JOB_CLASSES) pro Job Klasse überschrieben werden!

Steht dieser Wert auf einen deutlichen höheren Default, werden diese Einträge dann eben nicht mehr mittelfristig gelöscht.

D.h. die folgenden Punkte müssen überprüft werden:

  1. Wie voll ist das Log? Wie alt sind die Daten
  2. Ist der automatische Lösch-Job angelegt
    1. wie ist die Rentention Period parametrisiert - Bei Bedarf Wert anpassen
  3. Läuft der Job überhaupt regelmäßig
  4. Überschreiben Definition auf Klassen Ebene die eigentliche gewünschten Einstellungen auf globale Ebene
    1. Anpassen der Klassen Parameter
  5. Manuell das Log löschen

Wie voll ist das Log? Wie alt sind die Daten

Überprüfen mit:

SELECT COUNT(*)       AS count_log
      , MIN(log_date) AS first_log
      , MAX(log_date) AS last_log
      , trunc(MAX(log_date)) -trunc(MIN(log_date))  AS  log_tage 
   FROM dba_scheduler_job_log 
/
 
   COUNT_LOG  FIRST_LOG   LAST_LOG    LOG_TAGE
------------  ---------   ----------  -----------
       67538  04-NOV-16   01-SEP-20   1397

Wie ist der automatische Lösch-Job parametrisiert

 
SELECT * FROM DBA_SCHEDULER_GLOBAL_ATTRIBUTE;
 
 
ATTRIBUTE_NAME VALUE
------------------------------ --------------------
...
LOG_HISTORY 30
...

D.h. im Prinzip sollten nach 30 Tage alle Daten gelöscht werden (außer auf Klassen Ebene ist etwas anders definiert).

Parameter einstellen

Wird weniger Log benötigt, den Zeitraum z.B. auf 10 Tage kleiner einstellen:

sqlplus / AS sysdba
 
 
SYS@GPI> EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE('log_history','10');
 
PL/SQL PROCEDURE successfully completed.
 
 
SYS@GPI>SELECT VALUE 
          FROM DBA_SCHEDULER_GLOBAL_ATTRIBUTE 
         WHERE ATTRIBUTE_NAME='LOG_HISTORY';
 
VALUE
------
10

Lösch Job überprüfen

  SELECT js.owner
       ,  js.job_name
       ,  decode (js.state,  'SCHEDULED', 'SHUD',  'DISABLED', 'DIS',  'RUNNING', 'RUN',  js.state) AS state
       ,  js.JOB_CLASS
       ,  js.program_name
       ,  js.job_action
       ,  to_char (o.CREATED, 'dd.mm.yyyy hh24:mi') AS CREATED
       ,  js.run_count
       ,  js.failure_count
       ,  to_char (js.last_start_date, 'dd.mm hh24:mi') AS last_start_date
       ,  to_char (js.next_run_date, 'dd.mm hh24:mi') AS next_run_date
    FROM dba_scheduler_jobs js, dba_objects o
   WHERE     js.owner = o.owner(+)
         AND js.job_name = o.OBJECT_NAME(+)
         AND js.job_name LIKE 'PURGE_LOG'
ORDER BY owner, job_name
/

Was für Fehler liegen vor?

SELECT d.owner||'.'||d.job_name AS job_name
     ,l.job_class
     ,d.log_date
     ,d.status
     ,d.error# error_number
	   ,d.errors
     ,d.actual_start_date
     ,EXTRACT (SECOND FROM d.cpu_used)
                       + (  EXTRACT (MINUTE FROM d.cpu_used)
                          * 60)
                       + (  EXTRACT (HOUR FROM d.cpu_used)
                          * 60
                          * 60)  AS timeused
     ,l.additional_info
  FROM dba_scheduler_job_run_details d RIGHT JOIN dba_scheduler_job_log l ON (d.log_id = l.log_id)
  WHERE d.job_name LIKE 'PURGE_LOG'
    AND d.status != 'SUCCEEDED' 
 /

Ist der Job zum Beispiel nicht aktiv, als SYS User aktiveren mit:

EXECUTE dbms_scheduler.enable('PURGE_LOG');

Überschreiben Definition auf Klassen Ebene die eigentliche gewünschten Einstellungen auf globale Ebene

Überprüfen der Einstellungen der Job Klassen:

SELECT owner
     , job_class_name
     , logging_level
     , log_history
     , comments 
 FROM DBA_SCHEDULER_JOB_CLASSES 
ORDER BY  log_history
/
 
--------------------
 
OWNER
-------------------------------------------------
JOB_CLASS_NAME
-------------------------------------------------
LOGGING_LEVEL                      LOG_HISTORY
--------------------------------- ------------
COMMENTS
-------------------------------------------------
SYS
ORA$AT_JCNRM_OS
FULL                                   1000000
auto optimizer stats collection

D.h. für die Auto Job Klassen ist als Default 1.000.000 Tage hinterlegt, d.h. in unsere Fall werden bereist schon am 30.07.4758 die Daten von heute gelöscht. Wohl etwas spät …

Setzen pro Klasse:

sqlplus / AS sysdba
 
EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('ORA$AT_JCNRM_OS','log_history','30');
 
-- 
-- Für alle erzeugen und dann das Spool ausführen
 
SELECT 'exec DBMS_SCHEDULER.SET_ATTRIBUTE('''||JOB_CLASS_NAME||''',''log_history'',''30'');'  AS command
  FROM DBA_SCHEDULER_JOB_CLASSES 
 WHERE  nvl(LOG_HISTORY,0) > 30;
 
COMMAND
-------------------------------------------------------------------------------
EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('ORA$AT_JCURG_OS','log_history','30');
...
...
 
-- 
-- Kommando kopieren und wieder in SQL*Plus ausführen 
--
 
SYS@GPI>EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('ORA$AT_JCURG_OS','log_history','30');
 
PL/SQL PROCEDURE successfully completed.
 
 
--
-- Überprüfen
--
SELECT JOB_CLASS_NAME
     , LOG_HISTORY
  FROM DBA_SCHEDULER_JOB_CLASSES 
/
 
JOB_CLASS_NAME  LOG_HISTORY
--------------  ------------ 
ORA$AT_JCURG_OS 30
...

Das Log manuell löschen

Hart alles löschen

Laut Support Node „How To Purge DBA_SCHEDULER_JOB_LOG and DBA_SCHEDULER_WINDOW_LOG (Doc ID 443364.1)“ kann auch die folgende harte Methode verwendet werden:

..
TRUNCATE ON these two TABLES IS supported AND can be done AS
..
 
 
TRUNCATE TABLE sys.scheduler$_event_log;
TRUNCATE TABLE sys.scheduler$_job_run_details;

Selectiv löschen

Alles nach eingestellter Rentention Regel:

EXEC DBMS_SCHEDULER.PURGE_LOG();

Alle älter als x Tage im Job Log löschen:

 EXEC DBMS_SCHEDULER.PURGE_LOG(7,which_log=>'JOB_LOG');

Alle älter als x Tage im Window Log löschen:

 EXEC DBMS_SCHEDULER.PURGE_LOG(7,which_log=>'WINDOW_LOG');

Prüfen ob es geklappt hat:

 SELECT COUNT(*) 
   FROM dba_scheduler_window_log 
  WHERE log_date<sysdate -7;


Quellen

Oracle Support

  • How To Purge DBA_SCHEDULER_JOB_LOG and DBA_SCHEDULER_WINDOW_LOG (Doc ID 443364.1)
  • PURGE_LOG Job will purge all entries and ignore the setting of LOG_HISTORY (Doc ID 1270854.1)
Cookies helfen bei der Bereitstellung von Inhalten. Diese Website verwendet Cookies. Mit der Nutzung der Website erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Computer gespeichert werden. Außerdem bestätigen Sie, dass Sie unsere Datenschutzerklärung gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website. Weitere Information
"Autor: Gunther Pipperr"
dba/oracle_scheduler_log_pflege.txt · Zuletzt geändert: 2020/09/01 19:20 von gpipperr