SSIS的检查点(Checkpoint)实际上是一个用于保存Task组件的状态的文件,它记录控制流中Task组件的执行状态和变量的值。用户通过合理地配置Checkpoint,在Package运行出错之后,重新执行Package,可以跳过上一次已经成功执行的步骤,而直接从失败的地方重新执行,这就意味着,从哪里失败,从哪里执行,这可以大大提高Package失败后再次执行的效率。通常一个Package由多个控制流的Task组件和数据流组件构成,跑完整个Package会耗费的时间会比较长,例如,Package包含5个Task,前4个Task都执行成功,第5个Task执行失败,如果Package下次从第5个Task开始执行,那么再次执行Package将会节省大量的时间。
使Package在错误点重新执行,这是CheckPoint设计的目的,但是,Checkpoint文件只会保存Task级别的执行状态和变量的值,对于数据流Task中的源、转换和目的,Checkpoint不会记录其状态,这就意味着,必须把数据流任务作为一个整体来运行。
一,配置CheckPoint
通过配置CheckPoint,使Package在Task执行失败之后,记录发生错误的Task组件。当Package再次执行时,直接从出错的Task组件开始执行,而不用浪费时间,去重复执行已经成功的Task组件,这是SSIS的错误重试机制。而启用Checkpoint,需要配置Package级别和Task级别的属性。
1,配置Package级别的属性
启用Checkpoint,必须配置Package的三个属性:
- CheckpointFileName:用于指定Checkpoint文件存储的路径,如果Packge在运行时出现了错误并中断,那么这个文件将会保持中断时的运行快照。
- CheckpointUsage:指定Package使用Checkpoint的情况,共有3个有效值:
- Never:不使用CheckPoint,
- Always:每次都使用Checkpoint
- IfExists:如果Checkpoint文件,那么使用Checkpoint,这就意味着,只有当CheckPoint文件存在时,才会执行CheckPoint机制,读取CheckPoint文件的内容,从上次的错误点开始执行package。
- SaveCheckpoints:是Checkpoint的关键属性,指定是否存储Checkpoint,也就说,要启用Checkpoint,该属性必须设置为True。
2,配置Task级别的属性
只有当Package被Task失败的触发时,Package才会保存CheckPoint,因此,为了触发Package的Checkpoint,在Task失败时,必须使Package失败,这就需要配置Task级别两个属性FailPackageOnFail和FailParentOnFail。
FailPackageOnFailure:默认值是False,该属性用于指定当Task失败时,Package是否失败。
- True表示如果当Task失败时,使Package失败;当Package的属性SaveCheckpoints为True,并且CheckpointFileUsage为IfExists时,这将在故障点重新开始执行Package。
当Task失败时,只有把该属性 FailPackageOnFail 设置为True,CheckPoint才会把该Task记录下来;如果这个属性都设置为False,那么该Task的失败不会触发CheckPoint记录故障点。
FailParentOnFailure:作用于Task的容器,当Task位于容器内时,该属性指定Task的失败是否影响容器的状态:
- 把容器记录为故障点:把Task的FailParentOnFail属性设置为True,把Task的FailPackageOnFailure设置为Fasle,并把容器的FailPackageOnFailure设置为True。
- 把容器内得Task记录故障点:把容器内的Task的FailPackageOnFailure设置为True。
当把属性FailParentOnFailure设置ture时,Task会把失败状态向上传递到其父容器;当把属性FailParentOnFailure设置false时,Task不会把失败状态向上传递到其父容器。当把失败传递给父容器,并且父容器的FailPackageOnFail设置为True,那么父容器使Package失败,这会使得Checkpoint把容器记录为故障点。
二,CheckPoint过程解析
CheckPoint文件记录Package执行失败时的错误信息,在重新执行package时,Package读取该文件以确定从那个task开始。当Package执行成功时,不会生成CheckPoint文件;只有执行失败时,才会生成CheckPoint文件。
1,CheckpointUsage 的用法
为了启用Checkpoint,必须设置SaveCheckpoints为Ture。当SaveCheckpoints属性设置为True之后,Package每次执行都检查CheckpointUsage属性,对于SaveCheckpoints属性的不同设置,Package会有不同的行为。
- 当CheckpointUsage 为 IfExists 时,如果存在CheckPoint文件,那么执行CheckPoint,从CheckPoint文件中记录的错误点开始执行package;如果不存在CheckPoint文件,那么从头开始执行package。
- 当CheckpointUsage 为 Never 时,不会检查CheckPoint文件,不管是否存在CheckPoint文件,都不使用CheckPoint。
- 当CheckpointUsage 为 Always 时,始终检查CheckPoint文件,当CheckPoint文件不存在,Package会报错。
Error: Checkpoint file "xxx" failed to open due to error 0x80070002 "The system cannot find the file specified.".
Error: The package failed during execution because the checkpoint file cannot be loaded. Further execution of the package requires a checkpoint file. This error usually occurs when the CheckpointUsage property is set to ALWAYS, which specifies that the package always restarts.
2,解析Checkpoint的工作流程
通常情况下,项目中常用的配置是:
- SaveCheckpoints:为True
- CheckpointUsage:为IfExists
- CheckpointFileName:为Checkpoint文件的路径
在启用了检查点之后,Package的工作流程通常是:
- 第一步:检查 Checkpoint 文件是否存在,如果不存在,那么Package从头开始执行;如果存在,Package读取文件,并找到从哪一个 Task 开始执行,并且从中读取文件中保存的变量和连接信息。
- 第二步:更新每一个启用 Checkpoint (FailPackageOnFailure = True) 的Task的状态,把已经执行成功的Task的状态更新到 Checkpoint 文件。
- 第三步:如果Package执行失败,那么 Checkpoint 文件保留上一个执行成功的 Task 的信息。
- 第四步:如果Package执行成功,那么删除 Checkpoint 文件,当下一次启动Package时,从Package的第一个 Task 开始执行。
三,探索Task的Checkpoint
创建一个新的Package,添加两个Execute SQL Task,配置Task的属性,测试Task的Checkpoint工作流程。
1,配置Package的属性,开启CheckPoint机制
设置Package的Checkpoints属性为:
2,查看FailPackageOnFail=False的行为
当执行Package时,Task执行失败,但是CheckPoint文件没有生成,原因是没有设置Task的FailPackageOnFail属性,其保持默认值False。
也就时说,当FailPackageOnFail=False时,虽然Package执行失败,但是不会生成CheckPoint文件。
3,查看FailPackageOnFail=True的行为
把Task的 FailPackageOnFail 属性设置为true,重新执行Package之后,生成CheckPoint文件,内容是:
<DTS:Checkpoint xmlns:DTS="www.microsoft.com/SqlServer/Dts" DTS:PackageID="{97AB8700-8254-4D50-969C-B6E992C06D53}"> <DTS:Variables DTS:ContID="{97AB8700-8254-4D50-969C-B6E992C06D53}"/> <DTS:Container DTS:ContID="{6AA5C196-805F-404F-A987-16D318C26E3E}" DTS:Result="0" DTS:PrecedenceMap=""/> </DTS:Checkpoint>
有用的信息是<DTS:Container >中记录的“DTS:ContID”,这个ContID是Package成功执行的最后一个Task的ID,“DTS:Result=0”,表明Task执行成功。
修正错误点的SQL语句,再次执行Package,Package从上次失败的Task开始执行Package。
四,探索容器的Checkpoint
容器的Checkpoint配置,会比Task多一个属性FailParentOnFailure,应根据需要为容器配置该属性。总的来说,对容器有两种配置:
- 配置A:设置容器的Task属性:FailPackageOnFail=False,FailParentOnFailure=True,设置容器的属性:FailPackageOnFail=True。
- 配置B:设置容器的Task属性:FailPackageOnFail=True,FailParentOnFailure=False,容器的属性保持默认值。
1,探究配置A
设置Execute SQL Task 2的属性FailPackageOnFail=False,FailParentOnFailure=True,设置容器的属性FailPackageOnFail=True。
查看CheckPoint文件,内容是XML格式,有用信息是第一个<DTS:Contrainer>节,ContID是Task的ID,“DTS:Result=0”,表明Task执行成功。
<DTS:Checkpoint xmlns:DTS="www.microsoft.com/SqlServer/Dts" DTS:PackageID="{EB3A3226-0D11-425E-BA6F-E628375D4A7A}"> <DTS:Variables DTS:ContID="{EB3A3226-0D11-425E-BA6F-E628375D4A7A}"/> <DTS:Variables DTS:ContID="{8AF684D1-DAE9-422A-86C3-28E5469866F8}"/> <DTS:Container DTS:ContID="{B978F098-D7A1-47E1-9870-AED62CCD6FA1}" DTS:Result="0" DTS:PrecedenceMap="Y"/> <DTS:Container DTS:ContID="{5FDFEFEC-CFF0-4527-92BB-64EF54E9D0E6}" DTS:Result="0" DTS:PrecedenceMap=""/> </DTS:Checkpoint>
从该文件中,看到有两个<DTS:Contrainer>节,表明有两个Task执行成功,而实际上,只有Execute SQL Task 1执行成功,这是为什么?这是因为我们把Execute SQL Task 2的属性FailPackageOnFail设置为False,Task失败不会是Package也失败,所以Package认为该Task执行的结果是成功。
重新执行Package,查看执行情况,Package并没有从出错的Task开始执行,而是从出错的Task的下一个Task开始执行。
这种配置是不可取的,它会导致Package不能从失败的Task开始执行,这里仅仅是为了演示Task的FailParentOnFailure属性的用法。
2,探究配置B
设置Execute SQL Task 2的属性FailPackageOnFail=Ture,FailParentOnFailure=False,容器和其他Task保持默认值,也就是说容器的FailParentOnFailure=False,FailPackageOnFail=False。
<DTS:Checkpoint xmlns:DTS="www.microsoft.com/SqlServer/Dts" DTS:PackageID="{EB3A3226-0D11-425E-BA6F-E628375D4A7A}"> <DTS:Variables DTS:ContID="{EB3A3226-0D11-425E-BA6F-E628375D4A7A}"/> <DTS:Container DTS:ContID="{B978F098-D7A1-47E1-9870-AED62CCD6FA1}" DTS:Result="0" DTS:PrecedenceMap=""/> </DTS:Checkpoint>
有用信息是第一个<DTS:Contrainer>节,ContID是Task的ID,“DTS:Result=0”,表明Task执行成功,从Checkpoint文件中,可以看到只有一个Task执行成功,也就是Execute SQL Task1执行成功。
重新执行Package,查看执行情况,Package从出错的Task开始执行:
因此,通常情况下,请无视Task的FailParentOnFailure属性,保持其默认值,而直接配置Task的FailPackageOnFail属性,设置为True,就可以实现在错误点重新执行。
补充一句,对Task和容器的属性(FailParentOnFailure和FailPackageOnFail)配置不同的组合,会产生不同的行为,有兴趣的读者可以自行测试,本文不再赘述。
参考文档:
微软BI 之SSIS 系列 - 通过设置 CheckPoints 检查点来增强 SSIS Package 流程的重用性
Integration Services Checkpoints to restart package from failure