0

我正在尝试使用 SSIS 包在不稳定的线路上传输大约 10 亿行。因此,它一直在中途失败。我想要一些方法让它可以重新启动。我试图在源和目标之间进行查找转换,但这太慢了。有没有另一种方法可以在不影响性能的情况下做我想做的事情?

4

2 回答 2

2

我最初的方法是编写一个包,当它启动时,它会识别要传输的数据子集,记录它正在处理的子集并尝试传输该数据。如果它完成,那么它将该数据标记为已传输并退出。否则,它已经被炸毁了,那个包裹没有什么可做的。

另一个进程将运行 X 时间范围并尝试查找失败的传输(标记为进程中但比 Y 持续时间更早的子集)。然后它会从转移表中删除这些行或将它们标记为符合转移条件。一般的想法是那些坏掉的东西被标记为重做。

这是一个非常简单的设计,最难的部分是分段并跟踪已传输/未传输的内容,然后简单地设置一个 SQL 代理作业以每 N 个时间帧触发一次包。如果不是您的网络出现故障,那么像这样进行数据传输的好处是它允许您并行执行,从而获得最大的吞吐量。SSIS 团队在设置加载数据的记录时采用了类似的方法。他们还把这个系统搞砸了,但这也是意料之中的。

如果 1B 行系统正在进行大量更新,那么您的数据分段逻辑将需要一些机制来识别更改并确保将这些记录反馈到系统中,但由于您没有指定这是必要的,我将忽略现在它。

如果您尝试使用查找,请确保您只撤回绝对必要的内容。对于这种情况,我希望这是一个非常狭窄的密钥。如果您采用分段数据加载方法,请确保在查找转换中使用相同的分区逻辑。否则,您将在最终运行时撤回 (1B -1 *transferSize) 行数据,这无疑会对您的劣质网络造成严重破坏。

有很多概括性,但如果您想了解更多方面的细节,请大声疾呼。

于 2013-03-22T02:44:18.337 回答
1

一次做一百万行这样的事情值得吗

DECLARE @Counter Int, @ReturnCode Int
DECLARE @Rows INT = 1000000, @Goal INT = 1000000000
  WHILE (@Counter * @Rows < @Goal)
    BEGIN
      EXEC @returncode = xp_cmdshell 'dtexec /f "C:\\path\\package.dtsx" /SET \\package.variables [User::Counter].Value;"' + CONVERT(VARCHAR(10), @Counter) + '"'

      IF (@returncode = 0)
        BEGIN
          @Counter = @Counter + 1
          PRINT 'Failed this at this time dude: ' + CONVERT(VARCHAR(30), GETDATE())
        END
    END

然后在查询中的 oledb 源组件内部有一个 where 子句,例如

    WHERE TableID BETWEEN (SELECT MIN(TableID) FROM Table) + ((? - 1) * 1000000)) 
          AND (SELECT MIN(TableID) FROM Table) + (? * 1000000))

不过有几件事 - 我认为您必须在 SSIS 变量中的表达式中构建查询(您以前做过吗?这很简单,有时在子查询中使用参数会出错),您可能应该抓住 MIN (TableID) 只在开头一次并将其存储在变量中。

这一切都值得这么麻烦,你认为这会有所帮助吗?

于 2013-03-22T02:46:11.533 回答