Friday, July 8, 2011

SSIS的检查点文件用法

如果你是一个ETL应用程序开发人员或是管理员,那么你可能会遇到的一个问题就是发生失败后重新运行整个ETL应用程序。从失败处重新运行应用程序通常是不可能的,这有许多原因,但是主要是由于很难执行日志记录和维护应用程序的每一步以及配置基于可用日志的执行。SQL Server集成服务提供了一个在某种程度上自动从失败处重启处理的机制。这个机制是通过使用检查点文件来提供的。它帮助我们配置ETL解决方案在发生一个执行错误后的执行流。这篇文章解释了检查点文件和集成服务的一些有用任务的使用。
这篇文章包括:
· 建立检查点文档
· 在for loop中的检查点用法
· 在事件中的检查点用法
· 其它约束
建立检查点文档
检查点文件的配置从建立三个包的属性开始:CheckpointFileName、CheckpointUsage、SaveCheckpoints。 这些属性在检查点分类下和包的属性一样有效(看分类视图的属性)。CheckpointFileName 运行我们设置检查点文件的路径。因为信息是以XML格式存储的,给这个文件一个XML扩展会更好,不过这不是必需的(例如D:Checkpoint Files/LoadDataPackage.xml)。
第二个属性,CheckpointUsage 告诉集成服务这个包是否需要一个检查点文件。它可以使用三个值。Never、IfExists和Always。Never 表示没有使用检查点文件,包的执行必须从头开始(或者失败后重启)。Always 要求每一个执行使用检查点文件。一旦设置为Always,没有检查点文件包就不能启动。IfExists表示如果只存在检查点文件,那么包使用检查点文 件。IfExists是CheckpointUsage最好的设置,因为如果包发生错误,那么将只存在检查点文件。记住,一旦设置了检查点设置,包会在执 行过程中在给定位置创建检查点文件,然后在成功执行后将它删除。只有在失败的情况下才会将检查点文件保留下来。

SaveChekpoints 表示包是否需要保存检查点。它的值是true或false。如果包需要在失败后重启那么这个值要设置为true。
最后一步是配置每一个任务,指定检查点中要包含的内容。这通过FailPackageOnFailure 属性来完成。这个属性要求设置为True,使得检查点中的任务可用。
好了,让我们把这个建起来。打开商业智能开发套件,并启动一个新的集成服务项目。添加两个文件系统任务。创建三个变量用于为两个文本文件保存两个物理路径和一个为目的地保存的路径。如下面所示地命名变量。你可以根据你的文件夹结构改变路径。
SSIS的检查点文件用法
这是假定场景:我们从客户端接收两个文本文件到E:ClientsFiles文件夹下。一个包加载了这些文件并将它们拷贝到目的地(D:FilesReceived)。一旦拷贝了它们,它就提取数据并将其转换到数据库中的相关表中。你的包可能看起来是这样的:
SSIS的检查点文件用法
注意,因为这个样例显示了检查点的执行,转换和转移还没有执行,因此它们用两个脚本任务弹出窗口信息显示“记录成功保存!”来显示。现在创建两个文本文 件Transaction1.txt和Transaction2.txt。不要把它们拷贝到E:ClientsFiles下。现在像下面这样配置系统任 务:
SSIS的检查点文件用法
添加信息到两个脚本任务。现在包做好了。注意我们没有配置任何与检查点相关的东西。首先我们没有设置就运行包,然后了解问题,之后尝试使用检查点解决问题。

在开始之前,让我们确定包在运行。将两个文本文件都放在E:ClientsFiles文件夹下。运行这个包并观察文件是否拷贝到目的地 中和脚本任务的信息是否显示了。它应该是可以的。好了,让我们开始测试这个检查点。从源文件夹下删除Transaction2.txt 并运行它。输出应该如下面所示:
SSIS的检查点文件用法
加载Transaction2文件任务失败,因为没有可用的Transaction2.txt 文件。一旦这个文件可用了我们可以再次运行这个包,但是最大的问题是,它再次运行了第一个任务并再次加载了Transaction1.txt。因此,它可 能导致数据(或业务)错误或冗余(如果转换/转移执行了)。这就是我们所希望避免的,也是我们要使用检查点文件的地方。如果包执行失败了,我们需要从失败 处重启这个包,而不是从头开始。
让我们来进行配置。如下所示地改变属性:
SSIS的检查点文件用法
让我们再次运行这个包。确保源文件夹只包含了Transaction1.txt 文件。就像第一次一样,在第二个任务后包运行失败了。现在打开保存检查点文件的文件夹。你将看到创建了 SamplePackageCheckpoint.xml。之所以创建了这个文件是由于我们将包中的SaveCheckpoints值设置为True。因 为包执行失败所以没有删除这个文件。执行失败是由于加载Transaction2 文件的FailPackageOnFailure 属性设置为True了。
将Tranaction2.txt 文件放置在源文件下并运行这个包。你将看到包从加载Tranaction2文件任务开始并继续执行:
SSIS的检查点文件用法

它从第三个任务开始,因为检查点文件指导它这么做,而包使用了这个检查点文件因为CheckpointUsage属性设置为IfExists了。如果你检查检查点文件所在的文件夹,那你现在不会看到这个文件了。它已经被删除了,因为包执行成功了。
在for loop中的检查点用法
使用for loop 的检查点设置是不同的。我尝试在一个ETL测试应用程序中执行它时遇到了这个问题。为了了解它,让我们试一些简单的代码。
打开一个新的SSIS项目并添加一个For Loop 容器。创建一个叫做Year的变量并设置类型为Int32。设置Year的默认值为2004。假设这样一个场景:你需要从一个给定的年份做一些处理到当前 的年份。所以给定的年份是变量Year 的值。添加一个脚本任务到显示了这个处理的For Loop 容器上。在ScriptTask的ReadOnlyVaribles中添加变量Year,并添加一个信息框,它显示了如下信息:
以下是引用片段:
'code1
MsgBox("Calculationdoneforyear"&Dts.Variables("User::Year").Value.ToString()&".")
Dts.TaskResult=Dts.Results.Success

现在如下所示地配置For Loop 容器。注意我们在InitExpression上不设置@Year 的值。初始值会从变量那里得到。
SSIS的检查点文件用法
完成了!运行这个包。你将看到2004、2005、2006和2007年的信息。现在让我们开始配置检查点文件。如下所示地设置属性:
SSIS的检查点文件用法

因为我们需要在某一点上让包执行失败,所以改变脚本任务的代码,如下所示:
以下是引用片段:
'code2
If(CInt(Dts.Variables("User::Year").Value)=2005)Then
MsgBox("Erroroccurredwhileprocessingfor"&Dts.Variables("User::Year").Value.ToString()&".")
Dts.TaskResult=Dts.Results.Failure
Else
MsgBox("Calculationdoneforyear"&Dts.Variables("User::Year").Value.ToString()&".")
Dts.TaskResult=Dts.Results.Success
EndIf

再次运行这个包。这个包在执行2004年后失败。你将看到检查点文件已经创建了而且没有被删除。改变脚本任务的代码如它原来的样子(代码1)。因为包执 行失败了而有一个检查点文件可用,如果我们重启这个包,它将从失败处开始,它应该开始处理2005。重启这个包。它应该从失败处开始,但是它却是从处理 2004年开始。这是因为检查点文件说失败处的变量Year 是2004,这是错误的。变量Year 的值没有正确地保存。当For Loop 容器中任务的FailPackageOnFailure 属性的值设置为true 时会发生这样的情况。获取For Loop 容器中ScriptTask 的属性并设置FilaPackageOnFailure 为false。删除检查点文件。将ScriptTask 的代码改回代码2。再次运行这个包。
一旦包运行失败,将ScriptTask的代码改回代码1。包应该从失败处开始。检查先前执行所创 建的检查点文件。你将看到变量Year 的值被保存为2005,正如我们所期望的。运行这个包。注意For Loop容器从2005开始计数,如我们所期望的。这里重要的是,我们不应该将For Loop 容器中任务的FailPackageOnFailure 属性设置为True,即使你在里面有另一个For Loop容器(内置的)。

进一步的,我注意到当For Loop 容器包含了不止一个通过优先约束连接的任务时,失败发生后重启的时候,它从失败处开始For Loop容器,但是是从循环中的第一个任务开始而不是从失败的任务开始。这不管配置了怎样的设置都会发生;这证明我们没有控制检查点中for loop的任务的方法。
在事件中的检查点用法
我发现在事件执行上保存检查点也有点不同。而认识到这一点是非常重要 的,因为我们经常编写事件代码。一旦使用一个检查点文件取决于失败点重启了包,它会启动一些事件而另一些则不。让我们配置一个包用于测试。创建一个新的包 并添加一个脚本任务。设置检查点配置如下面所示:
SSIS的检查点文件用法
将下面的代码添加到脚本任务中去。它只是弹出一个信息。
以下是引用片段:
'code1
MsgBox("Scripttaskexecuted!")
Dts.TaskResult=Dts.Results.Success

配置脚本任务中的如下事件。添加一个脚本任务到每一个事件和显示这个事件的适当信息框的代码中去。
SSIS的检查点文件用法
注意,在事件中没有配置与检查点关联的设置。运行这个包用于测试。你将获得按上面的列表定制的信息。“Script task executed”信息将在OnPostValidate和OnInformation 事件之间显示。改变控制流中主要脚本任务的代码。
以下是引用片段:
'code2
MsgBox("Scripttaskfailed!")
Dts.TaskResult=Dts.Results.Failure

这会导致包执行失败。运行包并注意信息。包从OnPreExecute到OnPostValidate显示事件信息、主要的脚本任务信息,然后失败。这 会导致检查点文件仍然保存在文件夹中。如果你通过将代码2替换为代码1来修正错误并再次执行这个包,你将看到任务启动了但一开始的三个事件没有启动。它从 OnInformation事件开始启动事件。记住,即使事件中的脚本任务设置为FailPackageOnFailure = true 这个情况也是会发生的。当你对要执行事件的包使用检查点时要保持谨慎。
其它约束
检查点只能作用于控制流任务。与数据 流相关的任务不能被检查点控制。此外,ForEach Loop 容器也不能被检查点控制。它从头迭代这个循环,而不是从失败处启动。如果你需要从ForEach Loop 里失败任务处开始这个迭代,那么你需要在它上面执行你自己的代码。
你可能在包里包含了一些安全信息。如果使用了检查点,它可能在失败情况下在检查点文件里存储安全信息。因此,最好为检查点文档设置一个所有人都访问不到的安全位置。

souce: http://www.itvue.com/Article/DB/MSSQL/200903/5412.html

1 comment:

James Zicrov said...

Thank you so much for providing information about SSIS and many other aspects to look for whenever needed in crisis during compiling and debugging.

SSIS Upsert