【问题标题】:SSIS - Ultra large file (500MB) fails with OutOfMemory exceptionSSIS - 超大文件 (500MB) 因 OutOfMemory 异常而失败
【发布时间】:2018-08-24 13:15:14
【问题描述】:

我有一个 SSIS 包,它将数据从非标准 XML 文件加载到具有 xml 数据类型列的数据库表中。我称它为非标准文件,因为它有一些无效字符,例如我使用脚本任务删除的选项卡,并且其中有层次结构标签,这些标签可以用于某些键,而不能用于其他键。我曾尝试使用 XSLT,但它不起作用,因为所有属性(标签)在 SSIS XML 源中显示为单独的输出而不是单独的输出。因此,我将整个 XML 文件作为单列读取,将单行作为平面文件读取。该包在加载小文件(最大 8 Mb)时运行良好,但在大文件时失败。尝试加载 500 MB 文件时,脚本任务因 OutOfMemory 错误而失败。因此文件以较小的块发送。现在,脚本任务用于处理 90 MB 文件,但在 DFT 中失败,因为 SSIS 仅读取部分 XML 而不是整个文件,因此 DFT 在目的地失败。我将 MaxbufferRows 分别从 10000 行和 10 MB 的默认值调整为 1,将 DefaultBufferSize 调整为 100 MB。我发现平面文件源正在读取 8193 KB 数据(8388609 个字符)。

请指教。

注意:我正在运行 Citrix 的 SSIS 包。我将整个 xml 文档存储在一个表中,然后使用 .nodes 提取相关信息以存储在相关阶段表中。

【问题讨论】:

  • 实际上就是一个巨大的 xml 文件(大约 500M 个字符)。你不能把文件分成更小的块吗?
  • 另外,您在哪里运行包,在 SSDT 中还是在 SSIS 服务运行它?如果是后者,包是在32位模式下运行的吗?
  • 我在 Citrix 的 SSDT 中运行包。失败的原始文件大小超过 500 MB。此文件在清理步骤中失败(脚本任务删除 XML 的无效字符)。然后我请求以较小的块发送文件。发送了一个大小为 88 MB 的文件,该文件通过了上述脚本任务,但随后在随后的数据流任务中失败,在该任务中,我将所有文件内容作为单个值(单个 XML 文档)读取并加载到具有列的表中数据类型 XML。
  • 问题是源仅读取 xml 的一部分并尝试将其加载到目标表中,从而导致错误。我通过用平面文件替换目标表来检查这一点,因为由于源平面文件中的 DT_TEXT 列,我无法使用数据查看器。
  • SSDT 是 Visual Studio 的一部分,它只是一个 32 位应用程序,所以我并不惊讶它会耗尽内存(因为它需要将整个文件以及所有它是转换等)。为什么不部署和运行包? SSDT 用于开发。您的 SQL Server(应该比您的 Citrix Session 拥有更多的内存处理能力,并且作为 64 位应用程序运行。

标签: sql-server xml ssis


【解决方案1】:

在您的脚本任务中,打开StreamReader 以增量处理文件,并将其流式传输到 SQL Server 中的 nvarchar(max) 或 XML 列。无需在 SSIS 中加载整个内容。

SqlClient Streaming Support

编辑您的问题以包含一个精简文件,包括您需要示例时需要进行的转换。

【讨论】:

  • 这可能不适用于(可能实际上不会)与 XML 文件一起使用,因为需要匹配开始/结束标签。
  • @user1443098 我不明白为什么不这样做。
  • @David,我不明白您将如何在 nvarchar 列中以增量方式流式传输数据。如果 SSIS 以块的形式读取数据(取决于缓冲区大小),那么在第一次插入后会有多行需要更新。 XML 数据类型是毫无疑问的,因为不完整的记录会导致无效的 XML。
  • @Shaggy1755 我建议在脚本任务中使用 ADO.NET 流式独家加载。完全绕过 SSIS 管道。
  • @DavidBrowne-Microsoft 好的,假设您正在流式传输 XML 文件。至少您需要解析根标签,这当然涵盖了整个文件!因此,您的第一个电话需要阅读整个内容。流媒体没有帮助
猜你喜欢
  • 1970-01-01
  • 2020-05-09
  • 1970-01-01
  • 2017-07-05
  • 2020-11-14
  • 2018-03-12
  • 2014-07-29
  • 1970-01-01
  • 2015-11-26
相关资源
最近更新 更多