Zadanie agenta programu SQL Server kończy się niepowodzeniem i zwraca błąd 258

Ten artykuł zawiera wskazówki dotyczące rozwiązywania problemów, które powodują niepowodzenie zadań programu Microsoft SQL Server Agent i generuje kod błędu 258.

Objawy

Usługa SQL Server Agent jest uruchomiona, ale zaplanowane zadania agenta programu SQL Server nie są uruchamiane. Dzienniki programu SQL Server i agenta zawierają limity czasu sieci i uwierzytelniania oprócz nieudanych logowań.

W poniższym przykładzie pokazano komunikat o błędzie dodany do dzienników:

SQLServer Error: 258, TCP Provider: Timeout error [258]
ODBC Error: 0, Login timeout expired [SQLSTATE HYT00]
SQLServer Error: 258, Unable to complete login process due to delay in prelogin response [SQLSTATE 08001]
Logon to server '<ServerName>' failed (ConnLogJobHistory)

Przyczyna

Ten problem może być spowodowany dowolnym z następujących podstawowych problemów:

  • Blokowanie w tabelach systemu msdb używanych przez agenta SQL. To blokowanie uniemożliwia operacje odczytu i zapisu metadanych zadań.
    • Przykładowe tabele systemowe obejmują dbo.sysjobs, dbo.sysjobschedulersi dbo.jobsteps.
  • Brak odpowiedzi (zawieszenie) w ważnych wątkach agenta programu SQL Server lub innych problemach dotyczących poziomu procesu.
  • Wyczerpanie wątków roboczych w programie SQL Server (brak dostępnych wątków roboczych). To wyczerpanie uniemożliwia agentowi łączenie się lub przetwarzanie harmonogramów.

Rozwiązanie

  1. Sprawdź, czy usługa SQL Server Agent jest uruchomiona. Użyj jednego z następujących poleceń programu PowerShell:

    • W przypadku domyślnych wystąpień SQL:

      Get-Service -Name "SQLSERVERAGENT"
      
    • W przypadku nazwanych wystąpień SQL:

      Get-Service -Name "SQLSERVERAGENT$<InstanceName>"
      
  2. Jeśli usługa SQL Server Agent nie jest uruchomiona, uruchom ją przy użyciu jednego z następujących poleceń:

    • W przypadku domyślnych wystąpień SQL:

      Start-Service -Name "SQLSERVERAGENT"
      
    • W przypadku nazwanych wystąpień SQL:

      Start-Service -Name "SQLSERVERAGENT$<InstanceName>"
      
  3. Jeśli zadania nadal kończą się niepowodzeniem po uruchomieniu usługi SQL Server Agent, przejdź do następnego kroku. Jeśli zadania kończą się pomyślnie, problem zostanie rozwiązany i nie jest wymagana żadna dalsza akcja.

  4. Sprawdź zadania i harmonogramy w pliku msdb. Uruchom program SQL Server Management Studio (SSMS) i uruchom następujące zapytanie:

    USE msdb;
    GO
    -- List enabled jobs
    SELECT name, enabled, description 
    FROM msdb.dbo.sysjobs 
    WHERE enabled = 1;
    GO
    -- List schedules and next run information
    SELECT 
        s.name AS ScheduleName,
        j.name AS JobName,
        s.enabled AS ScheduleEnabled,
        s.active_start_date,
        s.active_end_time
    FROM msdb.dbo.sysjobs j
    JOIN msdb.dbo.sysjobschedules js ON j.job_id = js.job_id
    JOIN msdb.dbo.sysschedules s ON js.schedule_id = s.schedule_id
    WHERE j.enabled = 1;
    GO
    

    Przeanalizuj dane wyjściowe zapytania dla wszystkich zadań, które są włączone, ale zakończyły się niepowodzeniem. Zbadaj historię zadań i wyniki kroków dla wszelkich problematycznych zadań, aby zidentyfikować i rozwiązać podstawowe problemy.

  5. Wykryj sesje blokujące w msdb tabelach systemu agentów, uruchamiając następujące zapytanie w programie SSMS:

    USE msdb;
    GO
    SELECT 
        session_id, 
        blocking_session_id, 
        wait_type, 
        wait_duration_ms, 
        resource_description
    FROM sys.dm_os_waiting_tasks
    WHERE resource_description LIKE '%sysjobs%'
       OR resource_description LIKE '%sysjobschedulers%'
       OR resource_description LIKE '%jobsteps%';
    GO 
    
    • Aby zidentyfikować zapytanie skojarzone z sesją blokującą, uruchom następujące zapytanie w programie SSMS:

      SELECT 
          wt.session_id,
          wt.blocking_session_id,
          wt.wait_type,
          wt.wait_duration_ms,
          wt.resource_description,
          er.status,
          er.command,
          er.cpu_time,
          er.total_elapsed_time,
          txt.text AS sql_text
      FROM sys.dm_os_waiting_tasks wt
      LEFT JOIN sys.dm_exec_requests er 
             ON wt.session_id = er.session_id
      CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) AS txt
      WHERE wt.resource_description LIKE '%sysjobs%'
         OR wt.resource_description LIKE '%sysjobschedulers%'
         OR wt.resource_description LIKE '%jobsteps%';
      
  6. Rozwiąż lub zakończ wszystkie sesje blokujące zidentyfikowane w poprzednim kroku. Aby zakończyć sesję, uruchom następujące zapytanie w programie SSMS:

    Kill <Blocking_Session_ID>
    

    Po rozwiązaniu lub zakończeniu wszystkich sesji blokujących przejdź do następnego kroku.

  7. Sprawdź, czy nie występują problemy z kondycją pracownika, wątku lub zasobu, uruchamiając następujące zapytanie w SSMS:

    /* ============================================================
       HEALTH CHECK (Worker, CPU, Memory)
       ============================================================ */
    
    SELECT 
        Section,
        Metric,
        Value,
        ExtraInfo
    FROM (
    
        /* ===============================
           WORKER THREAD STATUS
           =============================== */
        SELECT 
            CAST('WORKER THREAD STATUS' AS VARCHAR(MAX)) AS Section,
            CAST(CONCAT('Scheduler ', scheduler_id) AS VARCHAR(MAX)) AS Metric,
            CAST(CONCAT('Workers: ', active_workers_count, '/', current_workers_count) AS VARCHAR(MAX)) AS Value,
            CAST(CONCAT('WorkQueue=', work_queue_count, ', Idle=', is_idle) AS VARCHAR(MAX)) AS ExtraInfo
        FROM sys.dm_os_schedulers
        WHERE scheduler_id < 255
    
        UNION ALL
    
        /* ===============================
           CPU PRESSURE
           =============================== */
        SELECT
            CAST('CPU PRESSURE' AS VARCHAR(MAX)) AS Section,
            CAST(CONCAT('Scheduler ', scheduler_id) AS VARCHAR(MAX)) AS Metric,
            CAST(CONCAT('RunnableTasks=', runnable_tasks_count) AS VARCHAR(MAX)) AS Value,
            CAST(CONCAT('PendingIO=', pending_disk_io_count) AS VARCHAR(MAX)) AS ExtraInfo
        FROM sys.dm_os_schedulers
        WHERE scheduler_id < 255
    
        UNION ALL
    
        /* ===============================
           MEMORY STATUS (System)
           =============================== */
        SELECT
            CAST('MEMORY STATUS' AS VARCHAR(MAX)) AS Section,
            CAST('SystemMemoryState' AS VARCHAR(MAX)) AS Metric,
            CAST(system_memory_state_desc AS VARCHAR(MAX)) AS Value,
            CAST(CONCAT('TotalMB=', total_physical_memory_kb/1024, 
                        ', AvailableMB=', available_physical_memory_kb/1024) AS VARCHAR(MAX)) AS ExtraInfo
        FROM sys.dm_os_sys_memory
    
        UNION ALL
    
        /* ===============================
           PAGE LIFE EXPECTANCY
           =============================== */
        SELECT
            CAST('PAGE LIFE EXPECTANCY' AS VARCHAR(MAX)) AS Section,
            CAST('PLE' AS VARCHAR(MAX)) AS Metric,
            CAST(cntr_value AS VARCHAR(MAX)) AS Value,
            CAST(NULL AS VARCHAR(MAX)) AS ExtraInfo
        FROM sys.dm_os_performance_counters
        WHERE counter_name = 'Page life expectancy'
          AND object_name LIKE '%Buffer Manager%'
    
    ) AS x
    ORDER BY Section, Metric;
    

    Zbadaj dane wyjściowe zapytania sprawdzania kondycji pod kątem dowolnego z następujących problemów określonych przez podane objawy:

    • Ciśnienie wątku roboczego:
      • Wyczerpanie pracowników, na przykład Workers: 512/512.
      • WorkQueue jest większy niż zero. Ta wartość wskazuje, że zadania oczekują, a system jest przeciążony.
    • Ciśnienie procesora CPU:
      • RunnableTasks wartość jest większa niż zero. Ta wartość wskazuje, że istnieje wąskie gardło CPU. Wartość niezerowa może również wskazywać, że harmonogram programu SQL Server jest monopolizowany przez wątek (harmonogram niepochodzący).
    • Presja na pamięć
      • Parametr Memory state ma wartość LOW. Ta wartość wskazuje, że system ma mało pamięci.
      • Niska wartość dla elementu AvailableMB. Ta wartość wskazuje wysokie użycie pamięci dla programu SQL Server.
      • PLE Jedna wartość mniejsza niż 300. Ta wartość wskazuje wysoki współczynnik zmian pamięci.
  8. Jeśli zidentyfikowano jakiekolwiek problemy z procesem roboczym, procesorem CPU lub pamięcią w poprzednim kroku, zmniejsz bieżące obciążenie, aby rozwiązać problemy. Jeśli nie zidentyfikowaliśmy żadnych problemów, przejdź do następnego kroku.

  9. Uruchom ponownie agenta programu SQL Server, uruchamiając jedno z następujących poleceń programu PowerShell:

    Ważne

    Ponowne uruchomienie agenta programu SQL Server przerywa wszystkie aktualnie uruchomione zadania.

    • W przypadku domyślnych wystąpień programu SQL Server:

      Restart-Service -Name "SQLSERVERAGENT"
      
    • Dla nazwanych wystąpień programu SQL Server:

      Restart-Service -Name "SQLAgent$<InstanceName>"
      
  10. Po ponownym uruchomieniu agenta programu SQL Server sprawdź, czy zadania są teraz uruchomione. Użyj Monitorowania Aktywności Zadań.