0

我正在从 C# 代码运行一个 SSIS 包,如下所示:

ErrorHandler errorHandler = new ErrorHandler();
Application app = new Application();
DTSExecResult res;
Package pkg = app.LoadPackage(packagePath, null);
res = pkg.Execute(null, null, errorHandler, null, null);

我有两个问题:

  1. 什么“引擎”运行这个包?SQL Server 是否运行它,或者只需要一个较小的 SSIS 引擎。

  2. 当这个 c# 代码(它是一个控制台应用程序)长时间运行时,它会逐渐消耗越来越多的内存。如何限制正在运行的包的内存使用量?

*想到的一个想法是,这种行为类似于 SQL Server 行为,即它占用内存并且从不释放它,当然是在定义的内存限制下。所以也许运行包的“引擎”设置了一定的内存限制,逐渐被填满。

4

1 回答 1

2

这是一些合理的推断——但并不准确。

  1. 运行包的“引擎”是您在 C# 应用程序中引用的库。它与 DTExec 中的代码相同 - 使用代理 SSIS 作业步骤时执行 SSIS 包(在 SQL 2008R2 及更低版本中)的实用程序。(SSIS2012 在服务中使用相同的代码执行它们,而不是可执行文件。)不需要安装 SQL Server 数据库服务。在您运行代码的机器上需要完整的 SQL Server 许可证。所需的 SQL 安装部分只是 SSIS“共享”组件。
  2. 在这个问题上我没有给你一个好的答案,因为我自己也遇到过类似的问题,还没有得到真正的答案。如果您观看任务管理器,您会发现私有工作集(您的进程实际使用的内存量)始终保持合理。是“提交大小”变得不合理。提交大小包括您的进程实际未使用但 Windows 已分配给它的内存。就我而言,在运行一个包很长一段时间后(它有一个循环来处理大量文件),我可以看到私有工作集稳定在 2GB,但看到提交大小增长并增长超过 4GB,直到包失败因为它无法获取内存。我不明白为什么会这样,因为我理解为我的进程保留了大量内存 t 实际上已经习惯了。我只能假设(没有根据)该进程在内部对内存进行了碎片化。它必须在这 4GB 中使用 2GB 的“散布”,使得散布在内存块周围的空白空间太小而无法填充任何请求。我不知道对内存进行“碎片整理”的 SSIS API 调用:)

我可以建议的是你创建你的包来限制自己。在我的情况下,使用循环,我可以实现“最大 20 个循环”,即使仍有文件要处理,程序包也会在 20 个循环后完成。返回值或数据库表可能表明还有更多的处理需要完成。在您的 C# 应用程序中,您可以循环调用 pkg.Execute,其中可能有一些 GC 尝试。我不知道这是否足以触发进程释放所获得的任何内存和/或连续重新分配它,但这就是我要尝试的。

于 2012-09-08T16:33:27.287 回答