SSIS数据流任务:内存不足异常

时间:2014-05-21 15:02:49

标签: ssis out-of-memory ssis-2012

以下是我的情况:我包含尽可能详细的信息,但如果您需要其他信息,请告诉我。我已经在网上搜索了一个小时左右而没有找到任何可以解决我的具体问题的帖子,所以任何帮助(甚至链接)都会受到赞赏。

我正在编写数据流任务,以便在我的数据源上执行SCD操作(使用Task Factory's SCD Component)。我通过极慢的连接从一个网络中的Oracle源加载到我的新服务器上的SQL源中。

SCD操作要求我从源和目的地提取数据,并比较两者。但是,这两个连接的相对速度对我来说是个问题:SQL源速度提高了近10倍,因此在旧服务器传输1时,数据流将从我的新服务器中提取800万条记录百万。

由于两个源都汇集在一起​​并流经同一个SCD组件,所以当我达到8m / 1m标记时,仍有7m行等待SQL源。据我了解,那些7m行在内存中等待通过SCD进行处理。

我收到SSIS调试主机已停止工作的错误消息,并且系统无法再向缓冲区写入新行。消息是在不同的组件和步骤(我有大约30个表具有相同的情况),所以我非常有信心这是我可用的内存的一般问题,而不是我的代码的特定问题包。此外,如果我运行单个表甚至表组,则程序包将始终成功 - 它只在尝试并行加载某些表时失败。

到目前为止采取的步骤:

1)将正在加载的表拆分为多个顺序容器/子包,以缓解内存压力:这大部分都有效,但会将整体执行速度降低到非常长的时间。此外,某些表在达到某个限制时仍然会抛出SSIS调试主机错误(下面)。

2)添加脚本组件以计算源上的哈希值(如this post),然后我可以使用它来确定记录是否已更改而不是比较每列。这也意味着我不需要从目标表中提取所有列,我认为这将有助于解决内存不足问题。

问题仍在继续:

一旦行计数不平衡达到极限水平,即使只从源和目标中拉出一些(6个日期时间,3个int,2个数字(38,0))列,我仍然会崩溃。这种情况发生在没有上面提到的哈希值的表上。下面是故障点的数据流的屏幕截图:注意行数。 enter image description here

关于下一步该做什么的想法 我想知道是否有办法减慢SQL源的速度,以便以与另一个相同的速度拉取记录?任何想法如何实现这个?

完整的错误说明: 1)SSIS调试主机已停止工作(弹出窗口)。

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: DtsDebugHost.exe
  Application Version:  2011.110.2100.60
  Application Timestamp:    4f35e2b2
      Fault Module Name:    clr.dll
  Fault Module Version: 4.0.30319.18449
  Fault Module Timestamp:   528fdc93
  Exception Code:   c0000005
      Exception Offset: 0010d0aa
      OS Version:   6.2.9200.2.0.0.272.7
  Locale ID:    1033
  Additional Information 1: 9336
  Additional Information 2: 9336482019c99e3f312ddc2ccd6c9a04
  Additional Information 3: b33b
  Additional Information 4: b33bc67c4e950cb436b9dbebdd26abc8

2)SSIS错误消息:

[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Exception adding key to cache) in ProcessInput sending row to cache.
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Exception adding key to cache) in ProcessInput adding rows to the cache.
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Exception adding key to cache) in ProcessInput.
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Unexpected exception in OrderedHashList.Remove removing entry from internal structures: Exception of type 'System.OutOfMemoryException' was thrown.) in ProcessKey thread dequeueing a key (03720200).
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Unexpected exception in OrderedHashList.Remove removing entry from internal structures: Exception of type 'System.OutOfMemoryException' was thrown.) in ProcessKey thread dequeueing a key (28740100).
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Internal error (Unexpected exception in OrderedHashList.Remove removing entry from internal structures: Exception of type 'System.OutOfMemoryException' was thrown.) in ProcessKey thread dequeueing a key (03720200).) in ProcessCache_Thread_ProcessKey.
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Internal exceptions encountered.) in ProcessInput.
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Internal error (Unexpected exception in OrderedHashList.Remove removing entry from internal structures: Exception of type 'System.OutOfMemoryException' was thrown.) in ProcessKey thread dequeueing a key (28740100).) in ProcessCache_Thread_ProcessKey.
[TF Dimension Merge Slowly Changing Dimension] Error: Internal error (Internal exceptions encountered.) in ProcessInput.

系统详细信息:

Windows Server 2012

已安装的内存(RAM):64.0 GB

系统类型:64位操作系统,基于x64的处理器

SSIS 2012 从Visual Studio环境执行(通过SQL Server代理运行作为计划作业时也会出现问题

3 个答案:

答案 0 :(得分:0)

我建议使用临时表首先从Oracle Source加载数据 - 这只是一个截断并且每次加载。使用Staging表作为SCD的源,而不是与Oracle的连接。

另一个选项(如果您是针对临时表)将是在SQL Server到达Task Factory SCD组件之前为数据插入Sort组件。确保根据您用于SCD的键执行排序。这会降低来自SQL服务器的数据的速度,也会使TF组件更快地执行SCD,因为行已经排序了。

答案 1 :(得分:0)

像往常一样,答案对于这个问题来说太简单了( ** headdesk ** 这里)。

原始开发人员请求我帮助改进包的性能,但没有对TaskFactory SCD的输入进行排序。这导致所有数据都缓存在内存中,直到结束时才允许通过SCD的行。

我被提示通过this comment thread进行检查,其中有人遇到类似的问题并被建议调整它。相关报价如下:

  

"该组件的行为与SCD向导的不同之处在于:它具有   多个输入而不是一个,它匹配输入上的行   非常类似于Merge Join组件而不是Lookup组件。   该架构的净效果是它必须存储传入   来自所有输入的行,直到它们与另一个的行匹配   输入,或者已知从这些输入中找不到匹配项   其他输入。 SCD向导可以处理它的单行输入   在一个时间,不需要缓存任何东西,因为它处理   一次输入一行,发出"查找"到现有维度   表格一次一行,以做出SCD处理决定。以来   这个组件缓存行,它需要更多的RAM来存储不匹配的   输入行。不幸的是,这个组件不监控可用   RAM级别并采取排序组件等替代操作   (将缓存发送到磁盘)。因此,如果RAM,它将抛出错误   已经筋疲力尽了。"

在我自己的包中,我遵循在源组件内进行排序的做法(即使用ORDER BY)。我没有检查这个软件包是否已经有了这个,我很少使用SSIS Sort组件,所以没有看到它就不会惊慌失措。

一旦我在包中配置了排序(this guy has a good summary here),性能大幅提升,我就能够无误地运行包。我将对这个人开发的所有包进行此更改,并且希望这能解决我的问题。

感谢@billinkc对PW组件的观察。它们不是为处理大型未分类输入(或具有不平衡速度的输入)而设计的,但一旦正确配置,看起来会好得多。

答案 2 :(得分:0)

1)您可以在将Oracle数据用于临时表之前使用HashBytes模式,然后再将其用于SCD转换。

2)否则,您也可以使用T-SQL MERGE语句来避免使用SCD转换。以下是一些详细解释的链接 - Merge Merge2