【问题标题】:SSIS package hangs while runningSSIS 包在运行时挂起
【发布时间】:2013-08-31 01:08:47
【问题描述】:

正如标题所暗示的,我在数据导入期间遇到了 SSIS 包问题。 我将尽力描述我能做到的最好的需求、采取的方法、问题以及我到目前为止所做的尝试。

需求:
将数据从 Excel 2007 文件(1.000.000 行)导入 SQL 表。
文件是在 UI 的帮助下上传的,所以包必须接收文件路径作为参数
导入不能阻塞 UI
在 SQL 级别应用额外的业务验证
知道包裹是否失败的可能性
失败时回滚的可能性

方法:
我已经创建了一个 SSIS 包并在 BIDS 中成功测试了它
在 xp_cmdshell
的帮助下创建了一个存储过程并调用了 dtexec 创建了一个不阻塞 UI 的作业(并且还能够确定导入/业务需求是否仍在运行
填充了一个表来存储包的参数(在我所做的研究中,我发现我无法将参数直接传递给作业或作业步骤)

构建对 dtexec 的调用的代码如下所示

DECLARE @SSIS NVARCHAR(4000) = '';
DECLARE @Params NVARCHAR(4000) = '/set \package.variables[FileName].Value;"\"' + @FileName + '\"" /set \package.variables[ConnectionString].Value;"\"' + @ConnectionString + '\""';
DECLARE @ExePath NVARCHAR(4000) = 'C:\"Program Files (x86)"\"Microsoft SQL Server"\100\DTS\Binn\'

SET @SSIS = @ExePath + 'dtexec /f "' + @PackageName + '" '
SET @SSIS = @SSIS + @Params

DECLARE @ReturnCode int
EXEC @ReturnCode = master..xp_cmdshell @SSIS

以及产生并由 xp_cmdshell 运行的行

C:\"Program Files (x86)"\"Microsoft SQL Server"\100\DTS\Binn\dtexec /f "C:\inetpub\wwwroot\pwc\\Import.dtsx" /set \package.variables[FileName].Value;"\"\\<server_name>\upload\Import.xlsx\"" /set \package.variables[ConnectionString].Value;"\"<connection_string>\""


问题:
在占用内存(在任务管理器中查看进程)的情况下,该程序包似乎在长时间运行(1h+)后挂起并且什么也不做,尽管它应该大约需要 25 分钟。
所以,我的问题是:
1. 什么可能导致包挂起并且无法完成
2. 当文件为 220mb 时,为什么 dtexec 占用约 2GB 内存(这是出于好奇;我可以忍受内存问题)

我尝试过的:
在 cmd 中运行该行。包运行成功,这让我觉得是 xp_cmdshell 的问题
我已经读到 xp_cmdshell 的权限可能存在问题,所以我目前正在以 SQL 管理员的身份运行该作业
我发现了一些可以解释正在发生的事情,但它与从应用程序运行包有关;如果这是问题,我会感谢一些有关 SQL 语法的帮助

非常感谢您帮助解决这个问题



更新
虽然手头的问题仍未解决,但我设法找到了解决需求的不同方法。
在我之前的声明中,我说过我不知道如何将参数传递给作业步骤。与此同时,我找到了一种方法。这不是一个真正的直接问题,但它确实解决了我的问题。 使用job step updatepermissions needed for update,我设法修改了作业步骤的注释字段

EXEC msdb.dbo.sp_update_jobstep
@job_name = N'StartImportFlow',
@step_id = 1,
@command  = <my command> ;

能够修改作业步骤,我将对包的调用从存储过程移至作业步骤。
需要提醒一件事:要执行从服务器代理打包的 DTS,该步骤必须在 sysadmin 帐户下运行,或者需要代理才能允许执行。



我很感激一些关于如何处理当前问题的提示:我应该将其标记为已回答还是应该让它这样来回答最初的问题?

【问题讨论】:

  • 尝试启用日志记录,这可能会让您了解它为什么挂起
  • @praveen 谢谢,但我已经为文本文件启用了日志,但据我所知没有错误,但坦率地说,日志输出有点超出我的理解
  • 为什么需要 xp_cmdshell 来执行。只需创建一个批处理文件并使用dtexec 实用程序运行SSIS 包。我不确定,但如您的链接中所述,可能是由于xp_xmdshell 包裹被挂起。请查看此链接social.msdn.microsoft.com/Forums/en-US/sqlintegrationservices/…
  • 我需要知道导入是否成功以继续满足业务需求并在任何时候出现任何错误时回滚所有内容。
  • 您需要使用事务才能在失败的情况下执行Rollback。尝试将您的组件包装在Sequence Container 中,并使transaction option=Required 和容器内的所有任务保持transaction option=Supported。查看这篇文章以了解 SSIS 中的事务msdn.microsoft.com/en-us/library/ms141144.aspx

标签: sql-server ssis


【解决方案1】:

根本原因

有一个带有 xp_cmdshell 的known issue 只允许处理一组双引号参数。

分辨率

  1. 您可以走工作步骤路线。这种方法的缺点是您只能运行一个实例。我不知道 UI 是如何实现的,但并发上传可能很难看。

  2. 创建一个运行包的批处理文件。它需要文件名和连接参数,这可能会让您只传入一组双引号参数。

  3. 我对不阻止 UI 的要求感到困惑,但它需要知道包失败。一种选择是让您的 UI 将所有启动参数写入一个表。然后有一个计划的进程每隔 N 个间隔运行一次,它使用所述参数启动这些包,并将结果写回该表或另一个表。您也可以直接从 UI 启动包。虽然您可以使用 dtexec,但此时您正在编写自定义代码,只需使用对象模型即可。

伪代码近似

using Microsoft.SqlServer.Dts;

string fileName = @"\\network\path\file.dtsx";
Application app = new Application();
Package p = app.LoadPackage(fileName, null);
p.Variables["FileName"].Value = @"\\network\path\file.xlsx";
p.Variables["ConnectionString"].Value = @"whatever works";
DTSExecResult results = currentPackage.Execute();

【讨论】:

  • 确实,正如我在更新中所说,我走上了工作路线并设法完成了我的需求。我想需要一些澄清(对不起,在初始帖子中缺少):运行一个实例不是问题,实际上是所需的业务需求。 UI 受限于并发上传。由于我一次只需要运行一个作业,因此我决定是否根据作业状态阻止 UI 控件。关于双引号问题,我知道。我在 xp_cmdshell 的初始测试中遇到了它。我认为这不是问题,因为它管理从 Excel 读取(使用约 2GB 内存 - 与 BIDS 相同)
【解决方案2】:

如果您在 64 位计算机上运行此程序包,使用 32 位版本的 dtexec.exe 将导致程序包挂起。使用 C:\Program Files,而不是 C:\Program Files (x86) 来获取 64 位版本。或者只是从 SQL 代理作业步骤执行包(使用 64 位版本。另外,不要在 64 位机器上使用执行包实用程序。它使用名为 dtexecUI 的 32 位 exe。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多