SQLServer-Agent-Auftragsverlauf

Einstieg

Zur Nachverfolgung der Aufträge (Jobs) des SQLServer-Agenten existiert ein Auftragsverlauf (History). Die eigentlichen Daten werden in der Tabelle msdb.dbo.sysjobhistory gespeichert. Über eine Option des SQLServer-Agenten kann die Länge des vorgehaltenen Auftragverlaufs automatisch begrenzt werden. Neben der maximalen Länge des gesamten Protokolls kann die maximale Zeilenanzahl je Auftrag angegeben werden.

Mit der Version 2005 kam bei den Einstellungen zum Auftragsverlauf (History) eine neue Option hinzu, die es ermöglichen soll den Verlauf zeitabhängig automatisch zu entfernen.

Automatismus?

Der Haken beim SQLServerAgent "Agentverlauf automatisch entfernen" ("Automatically remove agent history") macht nicht das, was man unter automatisch versteht und wie es in der Online-Doku beschrieben wurde. Stattdessen setzt das Management Studio bei Betätigung der OK-Taste (z. B. bei 6 Wochen) direkt folgendes Statement ab:

EXEC msdb.dbo.sp_purge_jobhistory  @oldest_date='11/23/2006 12:47:26'

Schaut man sich diese Prozedur mal etwas genauer an, so stellt man folgendes fest:

  1. Mit der Version 2005 wurde ein neuer Parameter eingeführt (@oldest_date)
  2. Dieser Parameter beschränkt die Löschung auf die Sätze vor dem Datum
  3. Ohne Datum werden alle Sätze aus dem Verlauf zu dem Job gelöscht
  4. Ohne übergebene Job-ID werden die Sätze von allen Jobs gelöscht

Wie geht es denn dann?

Wer übernimmt denn dann die Überwachung der Tabelle sysjobhistory, damit die angegebene Zeilenanzahl nicht überschritten wird? Die eigentliche Löschung des Auftragsverlaufs kann hiermit ja nicht erledigt werden, denn sp_purge_jobhistory berücksichtigt nur ein Datum.

Verfolgt man per Profiler die Aktivitäten des Agenten, so findet man nach Beendigung des Auftrags folgenden Aufruf:

EXECUTE msdb.dbo.sp_jobhistory_row_limiter @job_id

In dieser Prozedur findet man auch den Hinweis auf @max_total_rows und @max_rows_per_job die aus der Registry des Servers gelesen werden. Man kann dies selber ausprobieren:

DECLARE @max_total_rows         INT -- This value comes from the registry (MaxJobHistoryTableRows)
DECLARE @max_rows_per_job       INT -- This value comes from the registry (MaxJobHistoryRows)

-- Get max-job-history-rows from the registry
EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
                                       N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
                                       N'JobHistoryMaxRows',
                                       @max_total_rows OUTPUT,
                                       N'no_output'

-- Get the per-job maximum number of rows to keep
EXECUTE master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE',
                                       N'SOFTWARE\Microsoft\MSSQLServer\SQLServerAgent',
                                       N'JobHistoryMaxRowsPerJob',
                                       @max_rows_per_job OUTPUT,
                                       N'no_output'

select  @max_total_rows as max_total_rows, @max_rows_per_job as max_rows_per_job

Die angezeigten Werte entsprechen den Einstellungen beim Verlauf des SQLServer-Agenten.

Schlussfolgerung

In der Routine msdb.dbo.sp_jobhistory_row_limiter findet man keinen Bezug auf ein Datum wieder. Demzufolge kann diese Einstellung wohl doch nicht "automatisch" berücksichtigt werden. Die Option beim SQLServer-Agenten wird also nur einmalig angewendet, was auch erklärt, dass bei erneutem Aufruf das Häkchen wieder entfernt ist. Die Standard-Einstellung von 4 Wochen ist zusätzlich ungünstig gewählt, da der komplette Verlauf von Aufträgen, welche nur einmal im Monat starten, verloren gehen kann.