You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 2017 SSIS维护作业报错:execution_cursor不存在

解决SSIS Server维护作业报错“execution_cursor不存在”及后续作业超时问题

我之前也碰到过一模一样的情况,咱们一步步来捋清楚问题和解决办法:

首先先明确你遇到的核心问题:SQL Server 2017中的SSIS Server维护作业(负责清理旧执行日志)执行失败,报错游标execution_cursor不存在,重试3次都没成功;后续随着日志量超出正常范围,所有代理作业都因为查询超时失败了。

先把你提供的错误日志贴出来方便对照:

Date 5/23/2018 12:18:45 AM
Log Job History (SSIS Server Maintenance Job)
Step ID 1
Server KARABL3
Job Name SSIS Server Maintenance Job
Step Name SSIS Server Operation Records Maintenance
Duration 00:02:34
Sql Severity 16
Sql Message ID 16916
Operator Emailed
Operator Net sent
Operator Paged
Retries Attempted 3
Message Executed as user: ##MS_SSISServerCleanupJobLogin##. A cursor with the name 'execution_cursor' does not exist. [SQLSTATE 34000] (Error 16916). NOTE: The step was retried the requested number of times (3) without succeeding. The step failed.

问题根源分析

这个报错通常是因为SSIS维护作业依赖的内置存储过程[SSISDB].[internal].[cleanup_server_retention_window]执行时,游标execution_cursor的声明/释放逻辑出了异常——比如某次执行中途中断导致游标没正常释放,或者大日志量下游标逻辑冲突,导致后续执行时要么找不到游标,要么无法重复声明同名游标。

而后续所有作业超时,是因为SSISDB里的操作日志表(比如[SSISDB].[internal].[executions]、[SSISDB].[internal].[operation_messages])数据量爆炸,作业执行时查询这些表的时间过长,触发了超时阈值。

亲测有效的解决步骤

按顺序尝试下面的方法,基本能解决问题:

1. 手动执行清理脚本,修复游标异常

先手动运行核心清理逻辑,强制完成一次清理同时修复游标残留问题:

USE SSISDB;
GO
-- 先检查并清理残留的execution_cursor
DECLARE @cursorExists INT;
SELECT @cursorExists = 1 FROM sys.dm_exec_cursors(0) WHERE name = 'execution_cursor';
IF @cursorExists = 1
BEGIN
    DEALLOCATE execution_cursor;
END
-- 手动执行清理,这里保留7天日志,批量清理1000条,可根据你的需求调整参数
EXEC [internal].[cleanup_server_retention_window] 
    @retention_window = 7,
    @cleanup_batch_size = 1000;
GO

执行完后重新运行SSIS Server Maintenance Job,看看是否还会报错。

2. 调整维护作业的执行参数

如果手动执行有效,但自动作业还是失败,大概率是默认参数不适合你的日志量:

  • 打开SQL Server代理,找到SSIS Server Maintenance Job,进入SSIS Server Operation Records Maintenance步骤
  • 修改步骤的T-SQL命令,把@cleanup_batch_size调小(比如从默认10000改成1000),避免一次性处理太多数据导致游标逻辑崩溃
  • 同时可以把作业执行频率从每天一次改成每12小时一次,减少单次需要清理的数据量

3. 紧急清理超大日志表(已出现全作业超时的情况)

如果日志已经堆到所有作业都超时,先紧急分批清理旧日志缓解压力:

USE SSISDB;
GO
-- 重要!先备份SSISDB再操作
BACKUP DATABASE SSISDB TO DISK = 'D:\Backups\SSISDB_Before_Emergency_Cleanup.bak' WITH INIT;

-- 分批清理30天前的日志,重复执行直到数据量降到正常范围
DELETE TOP (10000) FROM [internal].[operation_messages]
WHERE operation_id IN (
    SELECT operation_id FROM [internal].[executions]
    WHERE start_time < DATEADD(day, -30, GETDATE())
);

DELETE TOP (10000) FROM [internal].[executions]
WHERE start_time < DATEADD(day, -30, GETDATE());
GO

用TOP分批删除是为了避免长时间锁表,导致其他作业彻底无法运行。

4. 修复SSISDB系统存储过程(极端情况)

如果以上方法都无效,可能是SSISDB的内置对象损坏了,重新生成一下:

-- 先停止SQL Server代理服务
USE master;
GO
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
GO
USE SSISDB;
GO
EXEC [internal].[refresh_internal_objects];
GO
-- 启动SQL Server代理服务

这个操作会重新生成SSISDB的内置存储过程和函数,修复可能的逻辑损坏。

后续预防措施

  • 定期监控SSISDB日志表的大小,避免数据量过度增长
  • 根据你的业务日志生成量,调整维护作业的保留窗口和批量清理大小
  • 开启SQL Server代理作业的失败通知,第一时间发现清理作业的异常,避免日志堆积

内容的提问来源于stack exchange,提问作者VahidSH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:16:29