本文提供有关导致MICROSOFT SQL Server 代理作业失败并生成错误代码 258 的问题的故障排除指南。
症状
SQL Server 代理服务运行,但计划的 SQL Server 代理作业不会运行。 除了登录失败之外,SQL Server 和代理日志还会显示网络和身份验证超时。
以下示例显示了添加到日志中的错误消息:
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)
原因
此问题可能由以下任何根本问题引起:
- 阻止 SQL 代理使用的 msdb 系统表。 此阻止可防止作业元数据的读取和写入操作。
- 示例系统表包括
dbo.sysjobs和dbo.sysjobschedulersdbo.jobsteps。
- 示例系统表包括
- 重要的 SQL Server Agent 线程或其他进程级问题中的无响应(挂起)。
- SQL Server 中的工作线程耗尽(没有可用的线程)。 这种耗尽会导致代理程序无法连接或处理时间表。
解决方案
验证 SQL Server 代理服务是否正在运行。 使用以下 PowerShell 命令之一:
对于默认 SQL 实例:
Get-Service -Name "SQLSERVERAGENT"对于命名的 SQL 实例:
Get-Service -Name "SQLSERVERAGENT$<InstanceName>"
如果 SQL Server 代理服务未运行,请使用以下命令之一启动它:
对于默认 SQL 实例:
Start-Service -Name "SQLSERVERAGENT"对于命名的 SQL 实例:
Start-Service -Name "SQLSERVERAGENT$<InstanceName>"
如果在启动 SQL Server 代理服务后作业继续失败,请转到下一步。 如果作业成功完成,问题就得到解决,无需执行进一步的操作。
检查
msdb中的作业和计划。 启动 SQL Server Management Studio (SSMS),并运行以下查询: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分析已启用但失败的任何作业的查询输出。 调查任何有问题的作业的作业历史记录和作业步骤输出,以识别和修复基础问题。
通过在 SSMS 中运行以下查询来检测代理系统表
msdb上的阻塞会话: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若要标识与阻止会话关联的查询,请在 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%';
解决或终止在上一步中标识的任何阻塞会话。 若要终止会话,请在 SSMS 中运行以下查询:
Kill <Blocking_Session_ID>解决或终止所有阻塞会话后,请转到下一步。
在 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;根据所给症状,确定运行状况检查查询的输出是否存在以下任何问题:
- 工作线程压力:
- 例如
Workers: 512/512,工人疲惫。 -
WorkQueue大于零。 此值指示任务正在等待,并且系统已重载。
- 例如
- CPU 压力:
-
RunnableTasks大于零。 此值指示存在 CPU 瓶颈。 非零值还可以指示 SQL Server 计划程序被线程(非生成计划程序)垄断。
-
- 内存压力:
-
Memory state是LOW。 此值指示整个系统内存不足。 - 一个低值
AvailableMB。 此值表示 SQL Server 的内存使用率较高。 -
PLE的值小于 300。 此值表示内存变动率较高。
-
- 工作线程压力:
如果在上一步中发现了任何工作进程、CPU 或内存问题,请减少当前工作负荷以解决这些问题。 如果未确定任何问题,请转到下一步。
通过运行以下 PowerShell 命令之一来重启 SQL Server 代理:
重要
重启 SQL Server 代理会中断任何当前正在运行的作业。
对于默认 SQL Server 实例:
Restart-Service -Name "SQLSERVERAGENT"对于命名的 SQL Server 实例:
Restart-Service -Name "SQLAgent$<InstanceName>"
SQL Server 代理重启后,请验证作业现在是否正在运行。 使用 作业活动监视器。