 | 级别: 初级 Cheung-Yuk Wu (wu@us.ibm.com), DB2 Warehouse Manager 架构师, 硅谷实验室,IBM Paul Wilms (dbwilms@us.ibm.com), 商业智能解决方案顾问, 硅谷实验室,IBM
2004 年 5 月 01 日 仓库管理员依靠仓库监控功能来检查和了解仓库的状态或“健康状况”。为此,DB2 Warehouse Manager 提供了 WIP,或称作“进行中的工作(Work in Progress)”。这篇文章中,我们展示了如何扩展 WIP 功能以保存 WIP 过去的历史以及收集各步状态中的附加修改。我们还提供了示例查询,仓库管理员用这些查询来检查仓库填充过程的历史记录。
WIP 概述
在 DB2 Warehouse Manager 中,Process Modeler 用于定义表示执行数据转换的步骤。这是关于仓库的静态信息。与执行这些步骤相关的活动维护在名为 IWH.EDITION 的 DB2® Warehouse Manager 内部目录表中,并且可通过 WIP GUI 来查看。
WIP 中将通过版本号来惟一识别与每一步的执行相关的信息,因为版本号是与特定的执行步骤相关联的。仓库管理员使用 GUI 来浏览和控制当前可在 WIP 中获得的每个版本的当前状态。
WIP 动态
WIP 窗口是一个极其动态的环境;版本的有关信息在 WIP 中频繁变化,用以反映何时调度转换步骤以及执行进度如何。对于维护在 WIP 中的每个版本,显示的是其最当前的状态。
图
1
以下情况会导致每个版本的记录不是永远保存在 WIP 中:当用户或系统清除一个版本时,当一个暂态步骤执行完毕时,以及当将一个步骤从生产级别降级时,等等。
换言之,WIP 不会维护每个版本的全部历史记录和版本经过的所有状态。然而也不应该对此感到惊讶,因为 WIP 本来代表的就是“进行中的工作(Work in Progress)”!
WIP 未提供的信息
WIP 中保存的确切信息有时候会被错误理解,而这可能导致对仓库中的数据状态做出错误结论。我们在这里将列举一些错误断言并解释错误的原因:
- WIP 包含了每个步骤最后执行的有关信息。
错!
- WIP 包含了每个步骤以前执行的有关信息。
错!
- WIP 包含了每个步骤最后一次执行中所经历的中间状态。
错!
- 版本号指示执行序列。
错!
WIP 并不包含有每一步最后一次执行的有关信息。只有在执行暂态步骤的时候,才能在 WIP 中看到其有关信息;而激活暂态步骤的那个步骤一旦完成,这些信息就会消失。如果有多个步骤成功填充了同一无版本目标表,那么在
WIP 中只能看到最后一个步骤填充目标表的有关信息。如果操作员手工清除最后一次执行记录,那么该版本就会消失。
小心处理 WIP!
WIP 中存储的信息量可能会极快地增长,特别是在每天运行很多步骤的情况下。因此,自然有热心的管理员去善意地执行清理操作。而这却可能导致灾难性的后果……
我曾看到一些热心的 WIP 操作员将成功的版本从 WIP 中清除。当然,其结果就是该版本对应的数据也被相应地删除。
可以将失败的版本从 WIP 中安全地清除,因为一个失败版本没有向目标表填充任何数据。促使操作员执行这些清除操作的一个动机就是,当 WIP 中的记录大量增加时,WIP 屏幕的刷新时间可能会很长。
WIP 功能的扩展技术
我们建议采用一种技术,以利用 WIP 中的数据向操作员提供更多信息,特别是以下方面的信息:以前历史、审计能力、状态更改的完全记录、附加的统计信息,以及更加容易的问题检测和解决(例如对于已发生或未发生的问题的可理解性,及其为何发生或未发生)。通过扩展 WIP 的功能,将达到我们的目标并且保存每个版本经过的所有不同状态。这一附加信息将使您可以:
- 维护所有以前执行的历史记录。
- 维护每个步骤经历过的所有中间状态的明细日志。
- 记录各步骤相关的调度程序是何时被启用和禁止的。
- 理解仓库目标表中的数据为何以及何时被意外地删除。
除了在 WIP 中可获得的信息之外,提供附加信息还有下列好处:
- 可以保存所有版本的完整历史。
- 可以周期性地将部分 WIP 历史记录存档为文件。
- 可以通过每个版本经过的中间状态来审计该版本过去运行时的行为。
- 可以获得与每个版本经过执行时间相关的附加统计信息,包括对于非 SQL 类型的步骤。
- 可以检测未按预定时间运行的步骤及其原因。
- 可以在一个表中立即浏览与一个版本、一个步骤或一组步骤相关联的所有严重错误。
保存 WIP 的完整历史
主要思想是截获 WIP 中出现的任何更改,并将该信息保存在单独的名为 WIP_FULL_ARCHIVE 的表中。该表包含了下列信息的副本:
- 插入到 WIP 中的记录:即每次创建一个新版本时。
- 在 WIP 中更新的记录:即每次由于版本状态更改而更新版本记录时。
- 从 WIP 中删除的记录:通过其删除的特定状态和时间标记将已删除记录插入 WIP_FULL_ARCHIVE 中。
表 WIP_FULL_ARCHIVE 因而包含每个版本的完整历史 —— 从设置好 WIP 扩展过程之时开始。最初用 IWH.EDITION 表中当前现有的信息填充该表。初始化之后,将通过触发器机制继续一点点地将数据从
IWH.EDITION 表添入档案表中:
- IWH.EDITION 表上的 after-update 触发器会将 IWH.EDITION 表中所更新的每一行复制到档案表中;其结果是向目标表插入一行,以记录每个版本的状态发生的每次更改。为 IWH.EDITION 表中每个版本插入的第一行记录的 status 值为“start”;但这一行不是通过该触发器捕获的,因为它是由插入操作产生的。
- IWH.EDITION 表上的 after-delete 触发器将获取从 IWH.EDITION 表删除的每一行,并且用一个由减号开头的
status 值和一个指示了删除日期及时刻的时间标志向档案表插入一行。
IWH.EDITION 表上的 after-insert 触发器并非很有用,因为它只能截获其 status 值为 start 的记录行。而这些行不含任何有用值,这些有用值只能在描述同一版本的其他行中找到。但其描述机制确保了将数据连续地从 IWH.EDITION 复制到 WIP_FULL_ARCHIVE 表,并且提供了每个版本整个生存期的全部历史记录。我们测试后发现触发器对于性能的影响极其微小。由于档案表的内容持续增长,而且如果频繁填充仓库,其增长速度可能会相当快,所以我们需要通过定期删除档案表中数据的方式来改进该方法。这将在后面的小节中进行描述。
挖掘包含 WIP 完整历史的表中的数据
我们定义了 3 个步骤,用以从记录了 WIP 完整历史的表中筛选数据并且计算出一些重要信息,这是一些关于已执行完毕的步骤、各步骤的中间状态以及各步骤调度的信息。而其输出就保存在下列表中:
表 STEPS_COMPLETED(图 2)保存了每个版本的有关信息,这些版本可以是已经成功完成的,是已经失败的,或是以返回警告代码而结束的。该表包含了在 WIP 中显示的所有字段;WIP 中为数值型代码值的字段值已被其显式值取代。其中还有一个表示执行时间的附加字段,这是通过将该步骤完成的时间减去填充该版本的起始时间而得出的。其时间间隔比该步骤从开始执行到结束所经过的时间要短一些。
图
2
该表中包含了无法在 WIP 中获得的信息:
- 一个步骤每次成功的执行记录;相比之下,WIP 最多只会包含一个步骤最后一次成功的执行记录。
- 一个步骤每次以失败或警告而终止的执行记录;与之相比,如果操作员决定清除该版本,那么 WIP 中可能已经删除了其中一些记录。
- DURATION 字段:执行各步骤所经过的时间,无论失败与否。相比之下,WIP 只提供 SQL 类型步骤的成功版本的信息。
表 STEPS_TEMPSTATUS(图 3)保存每个版本的中间状态,而这些状态是在该版本的执行期间被记录的(canceling、canceled、retrying、purging、purged、interrupted)。该表不包含
start 或 populating 状态的有关记录;因为该信息可以从保存该版本的其他记录中导出。当然,我们无需记录一个成功完成的、失败的或以警告消息结束的版本的终结状态,因为
STEPS_COMPLETED 表中保存了该信息。STEPS_TEMPSTATUS 表还包含了将每个版本从 WIP 删除的有关记录,其中含有与删除相应的时间标记。
图
3
该表包含了未在 WIP 中保存的信息:
- 每个经过了下列其中一种状态的版本的记录:purging、canceling、retrying、interrupted。在清除、取消或为填充而重试该版本之前,只能在
WIP 中短时间内看到这些临时状态。
- 每个被成功清除的版本的记录;在 WIP 中,被清除的版本的有关信息也将被删除。
- 被取消的版本的记录,即使它们已从 WIP 中清除。
- 正从 WIP 中被删除的每个版本的有关记录,其中包含了删除的时间。
表 WIP.STEPS_SCHEDULED 包含了各步骤的调度信息,以及已取消激活的已调度版本。当与已调度版本相应的步骤从生产级别降到测试或开发级别时,该版本将被取消激活。
图
4
该表包含了无法在 WIP 中获得的信息:
- 显示调度何时变为非活动的记录:当仓库管理员降级其中定义了一个或多个调度的步骤时,其调度就变为非活动的。
- 显示何时将调度覆盖的记录:如果 WIP 操作员决定立刻运行一个本来计划稍后才运行的版本时,就会出现该情况。因此,该版本不会在其初始指定的时间
Ti 运行,而是立刻运行;如果对该步骤指定了重复调度,那么则会在 WIP 中插入一个新版本,而其执行起始时间就是刚刚运行版本中初始指定的时间
Ti 加上其重复间隔。
- 关于过去已被调度的老版本的记录,即使它们可能已经被执行过了。而这些关于已经执行的被调度版本的记录在其执行之后就已从 WIP 中删除。
在本文的结尾,我们提供了一些固定的示例查询,将有助于用户从这些表中筛选出所需信息。附录中显示了这些表的完整定义。
除了刚才所描述的三个表之外,要获得包含了重要错误列表的表也很方便,且无需浏览从 WIP 环境中获得的许多日志页面。该工作极易完成,因为我们在
IWH.EDITION 表上定义了另一个触发器:当该表更新了一条记录并且该版本的状态为 failed 或 warning 类型时,与 IWH.LOGMSGS
表中版本有关的所有记录以及包含了错误消息的所有记录都将被写入 WIP.STEPS_ERRORS 表。附录中还提供了该表的确切结构。此表还包含了一个附加列
RESOLUTION_SUGGESTION,它并非是从 IWH.EDITION 提取的;该列由 WIP 操作员填入,用以包含动作的描述,而该动作是为校正执行时所碰到的错误而要采取的。当碰到不寻常的错误时该列的填写可能十分有用,便于在今后发生同样的错误时可应用快速的解决方案。
管理 WIP 历史表的大小
WIP 历史表 WIP_FULL_ARCHIVE 包含了每个版本的完整历史,并且被用作填充目标表 STEPS_COMPLETED、STEPS_TEMPSTATUS
和 STEPS_SCHEDULED 的源信息。表 WIP_FULL_ARCHIVE 的大小持续增长,因为触发器机制会将数据一点点地从 IWH.EDITION
表中填入档案表。这种设计并不可取,因而必须加以改进以确保控制好档案表的大小。而且要能够对过去仓库处理活动的任何历史加以恢复;备份文件应该包含从档案表中删除的数据。这可能是出于审计目的而需要的功能。我们还必须确保被定期激活以挖掘档案表并填充
3 个目标表的那些步骤会处理在同一时刻被插入到档案表中的数据。例如,只获得已完成的版本的有关信息,但是却遗漏了同一版本的各个中间状态的信息是极其不可取的。
改进后的设计是将 2 个表用于存档,取代目前的 WIP_FULL_ARCHIVE 表。表 WIP_ARCHIVE 是一个分级表。IWH.EDITION
表上所定义的触发器机制将连续填充该表。这是一个极其动态的表。而表 WIP_ARCHIVE_COPY 则包含了 WIP_ARCHIVE 表的快照复制;在执行复制时,同时也会将正在被复制的数据从原始的
WIP_ARCHIVE 表中删除。因此根据该数据转移的执行频率,WIP_ARCHIVE 表的大小可以保持得相当小。WIP_ARCHIVE_COPY
是一个更为静态的表;在每次执行从 WIP_ARCHIVE 表的转移时将替换它的内容。然后将筛选 WIP_ARCHIVE_COPY 表中的数据并进行转换,以生成目标表
STEPS_COMPLETED、STEPS_TEMPSTATUS 和 STEPS_SCHEDULED。
从 WIP_ARCHIVE 到 WIP_ARCHIVE_COPY 表的周期性转移将会由一个 UDP 步骤 Move WIP Data 来执行;该步骤将删除
WIP_ARCHIVE 表中的所有数据;而定义在 WIP_ARCHIVE 表上的 after-delete 触发器则会将所有删除的数据插入
WIP_ARCHIVE_COPY 表。
我们没有选择另一种通过定义 SQL 步骤来实现的方法,此 SQL 步骤将从 WIP_ARCHIVE 表中选择数据后插入 WIP_ARCHIVE_COPY
表,而 WIP_ARCHIVE_COPY 表上的 after-insert 触发器紧接着会删除 WIP_ARCHIVE 表中的数据。该方法虽然可以在两个表中产生完全相同的结果,但是其效率要低得多,因为这需要将
WIP_ARCHIVE 表中删除的数据与插入 WIP_ARCHIVE_COPY 表的数据一列一列地进行比较。
下图总结了出入 WIP_ARCHIVE 和 WIP_ARCHIVE_COPY 表的数据移动。
图
5
WIP 管理员将负责定义适当的进度表,以执行将数据移动到 WIP_ARCHIVE_COPY 表中和填充目标表这两步过程。假设
WIP 管理员决定每小时调度执行一次该过程;在这种情况下,WIP_ARCHIVE 表最多只包含一小时之内的数据。而 WIP_ARCHIVE_COPY
表包含了一个小时期间的所有数据,这些数据在其被移动之前是存在于 WIP_ARCHIVE 表中的。在本场景中,当数据刚刚被移到该表中时,它包含的信息要少于一个小时的,因为执行该步骤所需的时间导致了很小的时间差量。目标表
STEPS_COMPLETED、STEPS_TEMPSTATUS 和 STEPS_SCHEDULED 包含了从激活 WIP History
过程开始的所有历史信息,仍保留在 WIP_ARCHIVE 表中的最新信息(本例中,最多为最后一小时的活动)除外。
备份 WIP 信息
已经定义了一个步骤对 WIP_ARCHIVE_COPY 表中所包含的数据进行备份。一个导出步骤似乎恰好就可以了。然而,当多次执行该导出步骤时,每次都会替换其目标文件。而我们需要的是保存所有备份,并且能够快速识别哪个备份文件包含了哪些数据。我们定义了一个
UDP 步骤 WIP Export Data,用以从 WIP_ARCHIVE_COPY 表导出数据,以及创建一个其名字包含了时间标记的文件。而时间标记则对应着文件中所存储的最新数据。备份文件位于
IBM\\SQLLIB\\LOGGING 子目录中,并且以 .backup 为扩展名。
图
6
在 IBM\\SQLLIB\\LOGGING 子目录中的这些文件可用于审计仓库上所执行的所有活动。还可以将其中任何一个文件重新加载到仓库中,用以对特定的步骤执行进一步分析。
控制目标表的大小
STEPS_COMPLETED、STEPS_TEMPSTATUS、STEPS_SCHEDULED 和 WIP.STEPS_ERRORS 是 WIP 操作员将查询的目标表;这些表是在每次执行
WIP History 过程时以附加(append)模式加以填充的。由于这些表持续增长,所以 WIP 操作员需要定期将已废弃的信息从这些表中删除。
因为这四个表包含了相关的信息,所以应该小心地执行信息的清除。例如,如果您想要清除一个月之前的信息,我们就建议在 4 个表上一致地进行:从每个表删除的行应该对应于超过一个月以前完成执行的版本。
请注意,即使您不经意间从这些表中清除了过多的信息,也可以通过将档案文件的数据重新加载到 WIP_ARCHIVE_COPY 表中来加以恢复(STEPS_ERRORS 表除外)。
定义一个单步来从这四个表中删除某日期之前完成的版本的所有相关数据将会十分简单。
扩展 WIP 功能的完整过程
图 7 中显示了保存 WIP 历史的完整过程。
图
7
如下面的图 8 所示,表 WIP_ARCHIVE、WIP_ARCHIVE_COPY、STEPS_ERRORS 和 STEPS_START 的内容是由触发器来控制的。
图
8
表 WIP_ARCHIVE、STEPS_ERRORS 和 STEPS_START 的内容主要是由触发器来更新的。然而,就在激活触发器之前,我们用
IWH.EDITION 和 IWH.LOGMSGS 中所包含的当前信息初始化了这些表的内容。
初始化过程
初始化过程由 3 个步骤组成:Collect Step Errors、Collect Start Time 和 Initial WIP Archival。这些步骤分别初始填充表
STEPS_ERRORS、STEPS_START 和 WIP_ARCHIVE。当然,对于已经完成的步骤,我们将无法获得其中间执行状态的有关信息,因为它们没有被保存在目录中。还请注意,有些版本号将很可能丢失,因为正如前面所解释过的,有些版本在
IWH.EDITION 表中的生存期极其短暂。STEPS_ERRORS 表也可能没有包含所有已失败版本的错误,因为 IWH.LOGMSGS
目录表只保存最后的 n 条错误消息记录,而 n 是被默认设置为 1000 的。
下图中所表示的初始化过程仅仅在安装时被执行一次。
图
9
安装程序包
程序包的安装十分简单:
- 将文件 DWC_WIP.zip 解压到主要的根目录下。将会生成一个包含了所有必需文件的子目录 DWC_WIP。
- 执行批文件 WIP_Import。该批程序接收下列参数:控制数据库名、主机名、用户标识、口令。
- 打开 DB2 Data Warehouse Center。在 Warehouse Targets 文件中,找到名为 CDB 的仓库目标(Warehouse
Target)。打开其属性:在 Database 页面中,将 Database Name 字段修改为控制数据库的名字。然后修改用户标识和口令。
- 执行批文件 WIP_Execute(与 WIP_Import 的参数相同)。
- 这就完成了安装。重新打开 DB2 Data Warehouse Center,进入名为 Warehouse Monitoring 的主题区域(Subject
Area)并打开 WIP History 过程。指定对于 WIP History 过程的调度(例如,添加每天的执行调度)。
- 现在,将定期自动地填充和更新 WIP History 过程中的各种表。
挖掘目标表中的数据
由 WIP History 过程填充的目标表包含了极其详细的信息,并且可以被成功地挖掘出来以回答仓库管理员所感兴趣的各种问题。以下是仓库管理员可能考虑的示例问题列表:
- 在最后一次运行过程 X 时执行了哪些步骤?这些步骤运行成功了吗?
- 每个步骤在最后一次执行中是如何完成的?它花费了多长时间来完成?何时完成的?
- 自日期 X 以来,有哪些步骤失败了?
- 最后一次执行期间有哪些步骤失败了?每个失败的步骤有哪些相关错误?
- 哪些步骤是以返回代码 X 而结束的?我们能否找到建议的动作以解决未成功的执行?
- 某一次,一个步骤为何没执行?
- 一个步骤要花费多长时间来完成每一次运行?
- 在特定的时期内,有哪些统计数字与特定过程中各个步骤的成功执行有关?
- 哪些步骤需要重试以及要重试多少次?这些步骤最终是否会成功?
- 哪些被取消调度的步骤没有被重新调度或哪些步骤重写了其初始调度?
- 哪些步骤经过了某个特定状态?(例如 Purged、Canceled、Removed……)
WIP Questions 过程包含的示例步骤提供了以上问题的答案。
图
10
在该过程中定义的步骤是 DB2 存储过程。每个存储过程填充一个在每次执行时被完全刷新(即填充类型为 Replace)的目标表。极易对每个
DB2 存储过程中使用的 SQL 语句进行修改,以满足特定您的特定需要。而本小节开始所提到的问题将被转换成下列 SQL 语句。
在最后一次运行过程
X 时执行了哪些步骤?这些步骤运行成功了吗?
步骤名:Steps executed in Process
SQL 语句:
INSERT INTO WIP.STEPSRUN
(SELECT STEPNAME, PROCESSNAME, EDITIONNUMBER, EDITIONPROCESS, STATUSTYPE, SCHEDULETS, COMPLETEDTS, DURATION, RETRIES,
AGENTSITENAME, POPULATIONTYPE,
STEPGROUPTYPE
FROM WIP.STEPS_COMPLETED
WHERE ( PROCESSNAME = param1 AND
EDITIONPROCESS = (select max(EDITIONPROCESS) from WIP.STEPS_COMPLETED
where PROCESSNAME= param1 AND EDITIONPROCESS != 0)
)
ORDER BY EDITIONNUMBER)
|
参数:param1:一个过程名
图
11
每个步骤在最后一次执行中是如何完成的?它花费了多长时间来完成?何时完成的?
步骤名:Last execution of steps
注意:该查询将提供 WIP_ARCHIVE_COPY 表在最后一次刷新之前的最后一次执行状态。SQL 语句:
INSERT INTO WIP.LASTEXEC
( SELECT STEPNAME, PROCESSNAME, EDITIONNUMBER, EDITIONPROCESS,
STATUSTYPE, SCHEDULETS, COMPLETEDTS, DURATION, RETRIES
FROM WIP.STEPS_COMPLETED
WHERE EDITIONNUMBER in (select max(editionnumber) from wip.steps_completed
group by stepname, processname )
ORDER BY STEPNAME, PROCESSNAME )
|
参数:无(修改语句和存储过程以筛选出比如仅仅由一个代理站点运行的步骤或一个过程中的步骤非常容易)
图
12
自日期 X 以来,有哪些步骤失败了?
步骤名:Failed steps since date
SQL 语句:
INSERT INTO WIP.FAILEDSTEPS
( SELECT STEPNAME, PROCESSNAME, EDITIONNUMBER, EDITIONPROCESS, STATUSTYPE,
SCHEDULETS, COMPLETEDTS, DURATION, RETRIES
FROM WIP.STEPS_COMPLETED
WHERE (date(completedts) >= param1 AND ( STATUSTYPE = 'Failed' ) )
ORDER BY EDITIONNUMBER, COMPLETEDTS )
|
步骤名:Failed steps since date
参数:param1:进行搜索的起始日期
图
13
最后一次执行期间有哪些步骤失败了?每个失败的步骤有哪些相关错误?
步骤名:Errors associated with failed steps
SQL 语句:
INSERT INTO WIP.ALLERRORS
(SELECT STEPNAME, EDITIONNUMBER, MSGRECNUM, ERRORRC1, ERRORRC2, SQLSTATE,
SYSTEMMSG, DWCMSG, RESOLUTION_SUGGESTION
FROM WIP.STEPS_ERRORS
WHERE ( editionnumber in
(select editionnumber from WIP.STEPS_COMPLETED as S
where statustype='Failed' and editionnumber =
(select max(editionnumber)
from WIP.STEPS_COMPLETED
where stepname = S.stepname ))
)
ORDER BY EDITIONNUMBER, MSGRECNUM )
|
参数:无。(修改语句和存储过程以筛选出比如仅仅由一个代理站点运行的步骤或一个过程中的步骤非常容易)
Figure 14
哪些步骤是以返回代码
X 而结束的?我们能否找到建议的动作以解决未成功的执行?
步骤名:Steps with specific
error
SQL 语句:
INSERT INTO WIP.THIS_ERROR_IN_STEP
(SELECT STEPNAME, EDITIONNUMBER, ERRORRC1, ERRORRC2, SQLSTATE, DWCMSG,
RESOLUTION_SUGGESTION
FROM WIP.STEPS_ERRORS
WHERE ERRORRC1 = this_rc1 OR ERRORRC2 = this_rc2 )
|
参数:thisrc1:返回代码 1(整数)
thisrc2:返回代码 2(整数)
注意:正如之前所提到的,RESOLUTION_SUGGESTION 列必须由 WIP 管理员来管理。
图
15
某次,一个步骤为何没执行?一个步骤被调度为何时运行?
步骤名:Why did a step not run?
SQL 语句:
INSERT INTO WIP.RUN_SCHEDULE
( SELECT STEPNAME, STATUSTYPE, SCHEDULETS, STATUSRECORDEDTS, RESCHEDULE,
PROCESSNAME, EDITIONNUMBER, EDITIONPROCESS, SCHEDULEID
FROM WIP.STEPS_SCHEDULED
WHERE STEPNAME = step
ORDER BY STEPNAME, EDITIONNUMBER )
|
参数:step:步骤名
图
16
注解:该请求不会告诉我们步骤为何没有运行的所有原因。然而,它提供了以下这个问题的答案:一个假定已调度的步骤为何没有运行?在上面的示例中,我们了解到计划在
2003-05-09 的 19:40 运行的步骤没有运行,因为 WIP 管理员决定在 14:16:04 就向该版本发出 RUN Now 命令。由于这是一个间隔
6 小时的重复调度,所以系统自动调度了一个在 1:40 运行的新版本。但是在 14:20:26,WIP 管理员会将该步骤从生产级别降级,该调度因而就变成非活动的了。然后,WIP
管理员将为该步骤定义 2 个新的调度:一个重复发生,而另一个则只运行一次。在 2003-05-16 的 6:04,他会提升该步骤回到生产级别,而该调度也会变为活动的。
我们从这些较少的记录行所收集到的数据可以为审计目的以及理解步骤为何没有运行提供大量信息。请注意,由于没有捕获关于步骤之间级联的历史,所以我们将无法弄清楚一个级联的步骤为何没有执行。
一个步骤要花费多长时间来完成每一次运行?
步骤名:Duration of execution
SQL 语句:
INSERT INTO WIP.DURATION
(SELECT STEPNAME, EDITIONNUMBER, STATUSTYPE, DURATION, SCHEDULETS,
COMPLETEDTS, RETRIES
FROM WIP.STEPS_COMPLETED
WHERE WIP.STEPS_COMPLETED.STEPNAME = step
ORDER BY STATUSTYPE, DURATION )
|
参数:step:步骤名
图
17
注解:该结果可用以检测一个步骤何时花费了特别长的时间才完成,或检测该执行近来所花费的时间是否变长了(例如,由于代理超载了,不同的代理执行该步骤,或更改了修订包(fixpack))。请注意在本例中,步骤(edition
56)的相同执行却导致了一次失败和一次成功:该步骤首次失败了并且转入重试(retry)模式,而当它被重试时却成功了。其持续时间没有考虑重试延迟,因为这没有包含在执行时间中。
在特定的时期内,有哪些统计数字与特定过程中各个步骤的成功执行有关?
步骤名:Steps statistics
SQL 语句:
INSERT INTO WIP.STEPS_STATISTICS
(SELECT STEPNAME, max(duration), min(duration),
rtrim(char(avg( integer(substr(duration,1,2))*3600 +
integer(substr(duration,7,2))*60 + integer(substr(duration,14,2)))/3600))
|| ' hr ' ||
rtrim(char(mod(avg( integer(substr(duration,1,2))*3600 +
integer(substr(duration,7,2))*60 +
integer(substr(duration,14,2)) ), 3600)/60 ))
|| ' min ' ||
rtrim(char(mod( avg(integer(substr(duration,1,2))*3600 +
integer(substr(duration,7,2))*60 + integer(substr(duration,14,2)) ),60)))
|| ' sec' AS AVG_DURATION,
count(*) AS NBR_EXECUTIONS
FROM WIP.STEPS_COMPLETED
WHERE PROCESSNAME = process AND STATUSTYPE = 'Successful' AND
COMPLETEDTS >= starttime AND COMPLETEDTS <= endtime
GROUP BY STEPNAME )
|
参数:process:过程名
starttime:与所搜索的起始时期相应的时间标志
endtime:与所搜索的终止时期相应的时间标志
图
18
哪些步骤需要重试以及要重试多少次?这些步骤最终是否会成功?
步骤名:Steps with retry
SQL 语句:
INSERT INTO WIP.STEPS_RETRIED
(SELECT STEPNAME, EDITIONNUMBER, STATUSTYPE, SCHEDULETS, COMPLETEDTS,
DURATION, RETRIES, NUMBEROFRETRIES, RETRYDELAY
FROM WIP.STEPS_COMPLETED
WHERE RETRIES > 0
ORDER BY STEPNAME)
|
参数:无
图
19
注解:当重试步骤时,其重试延迟没有计算到执行持续时间之中。
哪些被取消调度的步骤没有被重新调度或哪些步骤重写了其初始调度?
步骤名:Steps descheduled
SQL 语句:
INSERT INTO wip.steps_descheduled
(SELECT stepname, editionnumber, statustype, schedulets, statusrecordedts
FROM wip.steps_scheduled as S1
WHERE (statustype='Schedule Inactive' AND
S1.statusrecordedts >= (SELECT MAX(statusrecordedts)
FROM wip.steps_scheduled
WHERE stepname= S1.stepname))
OR statustype='Schedule Overwritten')
|
参数:无
图
20
哪些步骤经过了某个特定状态?(例如
Purged、Canceled、Removed……)
步骤名:Steps with specific status
SQL 语句:
INSERT INTO WIP.THIS_STATUS
(SELECT STEPNAME, PROCESSNAME, STATUSTYPE, EDITIONNUMBER, SCHEDULETS,
STATUSRECORDEDTS
FROM WIP.STEPS_TEMPSTATUS
WHERE STATUSTYPE = status
ORDER BY STATUSRECORDEDTS )
|
参数:status:Purging、Purged、Removed、Canceling、Canceled、Interrupted
图
21
注解:本例中,我们搜索了“Removed”状态的版本。该状态表明该版本已被系统从 WIP 中删除,但是与其关联的数据未被删除。如果同一目标表正被一个新版本(同一步骤或不同步骤)以附加(append)模式加以填充,或者是“程序控制的(Program
Controlled)”就会出现该状态。而搜索“Purged”状态指示其数据被删除的版本。
结束语
仓库管理员感到相当困惑的一个难题就是:“我的数据仓库为何没有按预定方式而得到填充?”要回答该问题是极其困难的,因为仓库管理员没有在系统中保存所有必要的后台信息。因此,我们提出了一项技术以取得仓库步骤的所有暂态元数据信息,其中使用触发器机制来捕获实时状态信息。然后,将所捕获的数据转换并且存储在少量几个表中,而仓库管理员可以直接对这些表进行挖掘。该过程还提供了一个易于控制和管理的机制,以便
DBA 不必额外手工删除和清理存档的仓库元数据。对于需要定期审计的业务,该机制也已经准备就绪,以使我们可通过最少的设置工作来对其进行部署。我们还提供了一组示例,其中展示了仓库管理员现在可以立即回答的典型问题。
该项研究的进行属于客户互动(customer engagement)中的一部分。通过单击代码下载图标可以下载本文中描述的所有步骤和触发器的确切定义,而且可以将这些过程导入到您的仓库环境中。在同一
zip 文件中的 readme.txt 文件中还描述了其安装过程。
附录
用于 WIP History 过程的目标表定义
WIP.WIP_ARCHIVE
BUSINESSVIEW VARCHAR(80) NOT NULL
BUSINESSVIEWID VARCHAR(10)
EDITIONNUMBER INTEGER NOT NULL
STATUS SMALLINT NOT NULL
SCHEDULETS TIMESTAMP
COMPLETEDTS TIMESTAMP
STATUSRECORDEDTS TIMESTAMP
SCHEDULEID VARCHAR(10)
RESCHEDULE SMALLINT NOT NULL
SOURCEIRNAME VARCHAR(80)
SOURCEIRTYPE SMALLINT
TARGETIRNAME VARCHAR(80)
TARGETIRTYPE SMALLINT
NUMBEROFRETRIES INTEGER
RETRYDELAY INTEGER
RETRIES SMALLINT NOT NULL
AGENTSITENAME VARCHAR(80)
RETURNCODE INTEGER
TARGETIRDDDNAME VARCHAR(80)
BVTYPE INTEGER NOT NULL
PROCESSNAME VARCHAR(80)
STEPGROUPTYPE INTEGER NOT NULL
TARGETTABLEID VARCHAR(10)
EDITIONPROCESS INTEGER
WIP.WIP_ARCHIVE_COPY : same structure as the WIP.WIP_ARCHIVE table
WIP.STEPS_START
MSGBVNAME CHAR(80)
MSGBENUMBER INTEGER
PROCESSNAME VARCHAR(80)
STARTTIME TIMESTAMP
WIP.STEPS_ERRORS
MSGRECNUM INTEGER NOT NULL
EDITIONNUMBER INTEGER
STEPNAME VARCHAR(80)
ERRORRC1 INTEGER
ERRORRC2 INTEGER
SQLSTATE CHAR(5)
SYSTEMMSG VARCHAR(1000)
DWCMSG VARCHAR(2000)
RESOLUTION_SUGGESTION VARCHAR(512)
WIP.STEPS_COMPLETED
STEPNAME VARCHAR(80) NOT NULL
PROCESSNAME VARCHAR(80)
EDITIONNUMBER INTEGER NOT NULL
EDITIONPROCESS INTEGER
STATUSTYPE VARCHAR(20)
SCHEDULETS TIMESTAMP
COMPLETEDTS TIMESTAMP
DURATION VARCHAR(20)
SCHEDULEID VARCHAR(10)
RESCHEDULE VARCHAR(10)
SOURCEDBNAME VARCHAR(80)
SOURCEDBTYPE VARCHAR(20)
TARGETDBNAME VARCHAR(80)
TARGETDBTYPE VARCHAR(20)
NUMBEROFRETRIES INTEGER
RETRYDELAY INTEGER
RETRIES SMALLINT NOT NULL
AGENTSITENAME VARCHAR(80)
POPULATIONTYPE VARCHAR(20)
STEPGROUPTYPE VARCHAR(20)
STEPID VARCHAR(10)
WIP.STEPS_TEMPSTATUS
STEPNAME VARCHAR(80)
PROCESSNAME VARCHAR(80)
EDITIONNUMBER INTEGER NOT NULL
EDITIONPROCESS INTEGER
STATUSTYPE VARCHAR(20)
SCHEDULETS TIMESTAMP
STATUSRECORDEDTS TIMESTAMP
SCHEDULEID VARCHAR(10)
RESCHEDULE VARCHAR(10)
SOURCEDBNAME VARCHAR(80)
SOURCEDBTYPE VARCHAR(20)
TARGETDBNAME VARCHAR(80)
TARGETDBTYPE VARCHAR(20)
NUMBEROFRETRIES INTEGER
RETRYDELAY INTEGER
RETRIES SMALLINT NOT NULL
AGENTSITENAME VARCHAR(80)
POPULATIONTYPE VARCHAR(20)
STEPGROUPTYPE VARCHAR(20)
STEPID VARCHAR(10)
WIP.STEPS_SCHEDULED
STEPNAME VARCHAR(80) NOT NULL
PROCESSNAME VARCHAR(80)
EDITIONNUMBER INTEGER NOT NULL
EDITIONPROCESS INTEGER
STATUSTYPE VARCHAR(20)
SCHEDULETS TIMESTAMP
STATUSRECORDEDTS TIMESTAMP
SCHEDULEID VARCHAR(10)
RESCHEDULE VARCHAR(10)
SOURCEDBNAME VARCHAR(80)
SOURCEDBTYPE VARCHAR(20)
TARGETDBNAME VARCHAR(80)
TARGETDBTYPE VARCHAR(20)
AGENTSITENAME VARCHAR(80)
POPULATIONTYPE VARCHAR(20)
STEPGROUPTYPE VARCHAR(20)
STEPID VARCHAR(10)
Definition of steps in the WIP History process
Move WIP Data (UDP step)
delete from WIP.WIP_ARCHIVE
Export WIP Data (UDP step)
Uses the DB2 export to export data to a file; the filename contains a time stamp
Select Completed Steps (SQL step)
SELECT
case when length(businessview) = 0 then '- - -'
else businessview end AS STEPNAME,
WIP.WIP_ARCHIVE_COPY.PROCESSNAME AS PROCESSNAME,
WIP.WIP_ARCHIVE_COPY.EDITIONNUMBER AS EDITIONNUMBER,
WIP.WIP_ARCHIVE_COPY.EDITIONPROCESS AS EDITIONPROCESS,
case when status = 4 then 'Successful'
when status = 5 then 'Failed'
when status = 12 then 'Warning'
else char(status) end AS STATUSTYPE,
WIP.WIP_ARCHIVE_COPY.SCHEDULETS AS SCHEDULETS,
WIP.WIP_ARCHIVE_COPY.COMPLETEDTS AS COMPLETEDTS,
case when statusrecordedts is not null then
substr(char(mod(integer((completedts - integer(retries*retrydelay)
minutes) - statusrecordedts)/100000,10)),1,1) ||
substr(char(mod(integer((completedts - integer(retries*retrydelay)
minutes) - statusrecordedts)/10000,10)),1,1) ||
' hr ' ||
substr(char(mod(integer((completedts - integer(retries*retrydelay)
minutes) - statusrecordedts)/1000, 10)),1,1) ||
substr(char(mod(integer((completedts - integer(retries*retrydelay)
minutes) - statusrecordedts)/100, 10)),1,1) ||
' min ' ||
substr(char(mod(integer((completedts - integer(retries*retrydelay)
minutes) - statusrecordedts)/10, 10)), 1,1) ||
substr(char(mod(integer((completedts - integer(retries*retrydelay)
minutes) - statusrecordedts), 10)), 1,1) ||
' sec'
else '--?' end AS DURATION,
WIP.WIP_ARCHIVE_COPY.SCHEDULEID AS SCHEDULEID,
case when reschedule = 0 then 'None'
when reschedule = 1 then 'Recurring'
when reschedule = 2 then 'Continuing'
else char(reschedule) end AS RESCHEDULE,
case when length(sourceirname) = 0 then '- - -'
else sourceirname end AS SOURCEDBNAME,
case when sourceirtype = 0 then '- - -'
when sourceirtype = 1 then 'DB2 Common Server'
when sourceirtype = 2 then 'DB2 UDB version 1'
when sourceirtype = 3 then 'DB2 UDB for z/OS'
when sourceirtype = 4 then 'DB2 UDB for iSeries'
when sourceirtype = 5 then 'DB2 UDB for iSeries'
when sourceirtype = 6 then 'DB2 UDB for AIX'
when sourceirtype = 7 then 'DB2 UDB for AIX V1'
when sourceirtype = 8 then 'DB2 UDB for HP'
when sourceirtype = 9 then 'DB2 UDB for Sun'
when sourceirtype = 11 then 'DB2 UDB for Windows'
when sourceirtype = 12 then 'DB2 UDB for VM'
when sourceirtype = 13 then 'DB2 UDB for Sinix'
when sourceirtype = 14 then 'DB2 UDB for SCO'
when sourceirtype = 15 then 'DB2 UDB for VSE'
when sourceirtype = 16 then 'DB2 UDB ESE'
when sourceirtype = 17 then 'DB2 UDB'
when sourceirtype = 18 then 'DB2 UDB'
when sourceirtype = 19 then 'DB2 Federated Server'
when sourceirtype = 100 then 'DB2 UDB for Linux'
when sourceirtype = 101 then 'DB2 UDB on NUMA-Q'
when sourceirtype = 20 then 'Oracle'
when sourceirtype = 30 then 'Sybase'
when sourceirtype = 31 then 'Sybase'
when sourceirtype = 40 then 'Microsoft SQL Server'
when sourceirtype = 50 then 'Informix'
when sourceirtype = 60 then 'Generic ODBC'
when sourceirtype = 70 then 'Local File'
when sourceirtype = 71 then 'Remote File'
when sourceirtype = 72 then 'OLAP Cube'
when sourceirtype = 80 then 'VSAM'
when sourceirtype = 90 then 'IMS'
when sourceirtype = 130 then 'DB2 ESE'
else char(sourceirtype) end AS SOURCEDBTYPE,
case when length(targetirname) = 0 then '- - -'
else targetirname end AS TARGETDBNAME,
case when targetirtype = 0 then '- - -'
when targetirtype = 1 then 'DB2 Common Server'
when targetirtype = 2 then 'DB2 UDB version 1'
when targetirtype = 3 then 'DB2 UDB for z/OS'
when targetirtype = 4 then 'DB2 UDB for iSeries'
when targetirtype = 5 then 'DB2 UDB for iSeries'
when targetirtype = 6 then 'DB2 UDB for AIX'
when targetirtype = 7 then 'DB2 UDB for AIX V1'
when targetirtype = 8 then 'DB2 UDB for HP'
when targetirtype = 9 then 'DB2 UDB for Sun'
when targetirtype = 11 then 'DB2 UDB for Windows'
when targetirtype = 12 then 'DB2 UDB for VM'
when targetirtype = 13 then 'DB2 UDB for Sinix'
when targetirtype = 14 then 'DB2 UDB for SCO'
when targetirtype = 15 then 'DB2 UDB for VSE'
when targetirtype = 16 then 'DB2 UDB ESE'
when targetirtype = 17 then 'DB2 UDB'
when targetirtype = 18 then 'DB2 UDB'
when targetirtype = 19 then 'DB2 Federated Server'
when targetirtype = 100 then 'DB2 UDB for Linux'
when targetirtype = 101 then 'DB2 UDB on NUMA-Q'
when targetirtype = 20 then 'Oracle'
when targetirtype = 30 then 'Sybase'
when targetirtype = 31 then 'Sybase'
when targetirtype = 40 then 'Microsoft SQL Server'
when targetirtype = 50 then 'Informix'
when targetirtype = 60 then 'Generic ODBC'
when targetirtype = 70 then 'Local File'
when targetirtype = 71 then 'Remote File'
when targetirtype = 72 then 'OLAP Cube'
when targetirtype = 80 then 'VSAM'
when targetirtype = 90 then 'IMS'
when targetirtype = 130 then 'DB2 ESE'
else char(targetirtype) end AS TARGETDBTYPE,
WIP.WIP_ARCHIVE_COPY.NUMBEROFRETRIES AS NUMBEROFRETRIES,
WIP.WIP_ARCHIVE_COPY.RETRYDELAY AS RETRYDELAY,
WIP.WIP_ARCHIVE_COPY.RETRIES AS RETRIES,
case when length(agentsitename) = 0 then '- - -'
else agentsitename end AS AGENTSITENAME,
case when bvtype = 0 then 'Warehouse editions'
when bvtype = 1 then 'Replace'
when bvtype = 2 then 'Append'
when bvtype = 3 then 'Program Controlled'
when bvtype = 4 then 'Drop'
when bvtype = 5 then 'Update in place'
when bvtype = 6 then 'Multi wait support'
else char(bvtype) end AS POPULATIONTYPE,
case stepgrouptype when 0 then 'None'
when 1 then 'DB2 Utility: iSeries'
when 2 then 'DB2 Utility: z/OS'
when 3 then 'DB2 Utility: UDB'
when 4 then 'Warehouse Statistics'
when 5 then 'Old DB2 Program'
when 6 then 'OLAP Program'
when 7 then 'File Program'
when 8 then 'SQL'
when 9 then 'Warehouse Transform'
when 10 then 'Replication Program'
when 11 then 'User-defined Program'
when 12 then 'Notification Program'
when 13 then 'Publication Program'
when 14 then 'SAP Program'
when 15 then 'Web Program'
when 16 then 'i2 Program'
when 17 then 'Process Execution'
when 18 then 'Redbrick Program'
else '--?' end AS STEPGROUPTYPE,
case when length(businessviewid) = 0 then '- - -'
else businessviewid end AS STEPID
FROM WIP.WIP_ARCHIVE_COPY
WHERE ( status in (4, 5, 12) )
Select Temporary Status
SELECT
case when length(businessview) = 0 then '- - -'
else businessview end AS STEPNAME,
WIP.WIP_ARCHIVE_COPY.PROCESSNAME AS PROCESSNAME,
WIP.WIP_ARCHIVE_COPY.EDITIONNUMBER AS EDITIONNUMBER,
WIP.WIP_ARCHIVE_COPY.EDITIONPROCESS AS EDITIONPROCESS,
case when status = 1 then 'Scheduled'
when status = -1 then 'De-scheduled'
when status = 2 then 'Populating'
when status = 3 then 'Retrying'
when status = 4 then 'Successful'
when status = -4 then 'Removed'
when status = 5 then 'Failed'
when status = -5 then 'Removed'
when status = 6 then 'Canceled'
when status = 7 then 'Purged'
when status = 8 then 'Deleted'
when status = 9 then 'Canceling'
when status = -9 then 'Canceled'
when status = 10 then 'Purging'
when status = -10 then 'Purged'
when status = 11 then 'Interrupted'
when status = 12 then 'Warning'
when status = -12 then 'Removed'
else char(status) end AS STATUSTYPE,
WIP.WIP_ARCHIVE_COPY.SCHEDULETS AS SCHEDULETS,
WIP.WIP_ARCHIVE_COPY.STATUSRECORDEDTS AS STATUSRECORDEDTS,
WIP.WIP_ARCHIVE_COPY.SCHEDULEID AS SCHEDULEID,
case when reschedule = 0 then 'None'
when reschedule = 1 then 'Recurring'
when reschedule = 2 then 'Continuing'
else char(reschedule) end AS RESCHEDULE,
case when length(sourceirname) = 0 then '- - -'
else sourceirname end AS SOURCEDBNAME,
case when sourceirtype = 0 then '- - -'
when sourceirtype = 1 then 'DB2 Common Server'
........
when sourceirtype = 90 then 'IMS'
when sourceirtype = 130 then 'DB2 ESE'
else char(sourceirtype) end AS SOURCEDBTYPE,
case when length(targetirname) = 0 then '- - -'
else targetirname end AS TARGETDBNAME,
case when targetirtype = 0 then '- - -'
when targetirtype = 1 then 'DB2 Common Server'
........
when targetirtype = 90 then 'IMS'
when targetirtype = 130 then 'DB2 ESE'
else char(targetirtype) end AS TARGETDBTYPE,
WIP.WIP_ARCHIVE_COPY.NUMBEROFRETRIES AS NUMBEROFRETRIES,
WIP.WIP_ARCHIVE_COPY.RETRYDELAY AS RETRYDELAY,
WIP.WIP_ARCHIVE_COPY.RETRIES AS RETRIES,
case when length(agentsitename) = 0 then '- - -'
else agentsitename end AS AGENTSITENAME,
case when bvtype = 0 then 'Warehouse editions'
when bvtype = 1 then 'Replace'
when bvtype = 2 then 'Append'
when bvtype = 3 then 'Program Controlled'
when bvtype = 4 then 'Drop'
when bvtype = 5 then 'Update in place'
when bvtype = 6 then 'Multi wait support'
else char(bvtype) end AS POPULATIONTYPE,
case stepgrouptype when 0 then 'None'
when 1 then 'DB2 Utility: iSeries'
........
when 18 then 'Redbrick Program'
else '--?' end AS STEPGROUPTYPE,
case when length(businessviewid) = 0 then '- - -'
else businessviewid end AS STEPID
FROM WIP.WIP_ARCHIVE_COPY
WHERE status not in (-1, 1, 2, 4, 5, 12)
Select Scheduled Steps
SELECT
case when length(businessview) = 0 then '- - -'
else businessview end AS STEPNAME,
WIP.WIP_ARCHIVE_COPY.PROCESSNAME AS PROCESSNAME,
WIP.WIP_ARCHIVE_COPY.EDITIONNUMBER AS EDITIONNUMBER,
WIP.WIP_ARCHIVE_COPY.EDITIONPROCESS AS EDITIONPROCESS,
case when status = 1 then 'Scheduled'
when status = -1 then 'Schedule Inactive'
when status = 4 then 'Schedule Overwritten'
else char(status) end AS STATUSTYPE,
WIP.WIP_ARCHIVE_COPY.SCHEDULETS AS SCHEDULETS,
WIP.WIP_ARCHIVE_COPY.STATUSRECORDEDTS AS STATUSRECORDEDTS,
WIP.WIP_ARCHIVE_COPY.SCHEDULEID AS SCHEDULEID,
case when reschedule = 0 then 'None'
when reschedule = 1 then 'Recurring'
when reschedule = 2 then 'Continuing'
else char(reschedule) end AS RESCHEDULE,
case when length(sourceirname) = 0 then '- - -'
else sourceirname end AS SOURCEDBNAME,
case when sourceirtype = 0 then '- - -'
when sourceirtype = 1 then 'DB2 Common Server'
.........
when sourceirtype = 90 then 'IMS'
when sourceirtype = 130 then 'DB2 ESE'
else char(sourceirtype) end AS SOURCEDBTYPE,
case when length(targetirname) = 0 then '- - -'
else targetirname end AS TARGETDBNAME,
case when targetirtype = 0 then '- - -'
when targetirtype = 1 then 'DB2 Common Server'
........
when targetirtype = 90 then 'IMS'
when targetirtype = 130 then 'DB2 ESE'
else char(targetirtype) end AS TARGETDBTYPE,
case when length(agentsitename) = 0 then '- - -'
else agentsitename end AS AGENTSITENAME,
case when bvtype = 0 then 'Warehouse editions'
when bvtype = 1 then 'Replace'
when bvtype = 2 then 'Append'
when bvtype = 3 then 'Program Controlled'
when bvtype = 4 then 'Drop'
when bvtype = 5 then 'Update in place'
when bvtype = 6 then 'Multi wait support'
else char(bvtype) end AS POPULATIONTYPE,
case stepgrouptype when 0 then 'None'
when 1 then 'DB2 Utility: iSeries'
........
when 18 then 'Redbrick Program'
else '--?' end AS STEPGROUPTYPE,
case when length(businessviewid) = 0 then '- - -'
else businessviewid end AS STEPID
FROM WIP.WIP_ARCHIVE_COPY
WHERE
status in (1, -1)
or ( status=4 and completedts < schedulets)
Definition of triggers
CREATE TRIGGER WIP.EDITION_UPD AFTER UPDATE ON IWH.EDITION
REFERENCING NEW AS n FOR EACH ROW MODE DB2SQL
BEGIN ATOMIC
insert into WIP.WIP_ARCHIVE
select n. BUSINESSVIEW, n.BUSINESSVIEWID, n.EDITIONNUMBER,
n.STATUS, n.SCHEDULETS, n.COMPLETEDTS,
case when n.status in (1, 6, 10) then CURRENT TIMESTAMP else null end,
n.SCHEDULEID, n.RESCHEDULE, n.SOURCEIRNAME, n.SOURCEIRTYPE,
n.TARGETIRNAME, n.TARGETIRTYPE, n.NUMBEROFRETRIES, n.RETRYDELAY,
n.RETRIES, n.AGENTSITENAME, n.RETURNCODE, n.TARGETIRDDDNAME,
n.BVTYPE, n.PROCESSNAME, n.STEPGROUPTYPE, n.TARGETTABLEID,
n.EDITIONPROCESS
FROM IWH.EDITION
WHERE editionnumber=n.editionnumber and businessviewid=n.businessviewid;
END$
CREATE TRIGGER WIP.EDITION_UPD2 AFTER UPDATE ON IWH.EDITION
REFERENCING NEW AS n FOR EACH ROW MODE DB2SQL
WHEN ( n.status= 5 or n.status=12 )
BEGIN ATOMIC
insert into WIP.STEPS_ERRORS
select msgrecnum, msgbenumber, msgbvname, errorrc1, errorrc2,
errorsqlstate, substr(errorsystemmsg,1,1000),
substr(errorvwmsg,1,2000), '- - -'
FROM IWH.LOGMSGS
WHERE errorrc1 != 0 and msgbenumber !=0 and
msgbenumber= n.editionnumber and rtrim(msgbvname)=n.businessview;
END$
CREATE TRIGGER WIP.EDITION_DEL AFTER DELETE ON IWH.EDITION
REFERENCING OLD AS o OLD_TABLE AS WIP_TEMP FOR EACH ROW MODE DB2SQL BEGIN ATOMIC
insert into WIP.WIP_ARCHIVE
select o. BUSINESSVIEW, o.BUSINESSVIEWID,o.EDITIONNUMBER, -o.STATUS,
o.SCHEDULETS, o.COMPLETEDTS, CURRENT TIMESTAMP, o.SCHEDULEID,
o.RESCHEDULE, o.SOURCEIRNAME, o.SOURCEIRTYPE, o.TARGETIRNAME,
o.TARGETIRTYPE, o.NUMBEROFRETRIES, o.RETRYDELAY, o.RETRIES,
o.AGENTSITENAME, o.RETURNCODE, o.TARGETIRDDDNAME, o.BVTYPE,
o.PROCESSNAME, o.STEPGROUPTYPE, o.TARGETTABLEID,o.EDITIONPROCESS
FROM WIP_TEMP;
END$
CREATE TRIGGER WIP.WIP_ARCHIVE_DEL AFTER DELETE ON WIP.WIP_ARCHIVE REFERENCING OLD_TABLE AS WIP_TEMP FOR EACH
STATEMENT MODE DB2SQL
BEGIN ATOMIC
delete from WIP.WIP_ARCHIVE_COPY;
insert into WIP.WIP_ARCHIVE_COPY select * from WIP_TEMP;
END$
CREATE TRIGGER WIP.ARCHIVE_COPY_INS AFTER INSERT ON WIP.WIP_ARCHIVE_COPY REFERENCING NEW AS n FOR EACH ROW MODE
DB2SQL
WHEN (n.status in (4,5,12) )
BEGIN ATOMIC
update WIP.WIP_ARCHIVE_COPY
set statusrecordedts=
(select max(starttime)
FROM WIP.STEPS_START
WHERE msgbenumber = n.editionnumber and
rtrim(msgbvname) = n.businessview and
starttime < n.completedts )
where editionnumber = n.editionnumber and status in (4,5,12) and
businessview = n.businessview and schedulets = n.schedulets;
update WIP.WIP_ARCHIVE_COPY
set statusrecordedts= n.schedulets
where length(businessview) = 0 and processname = n.processname and
status in (4,5,12) and schedulets = n.schedulets and
completedts =n.completedts;
END$
CREATE TRIGGER WIP.LOGMSGS_INS AFTER INSERT ON IWH.LOGMSGS
REFERENCING NEW AS n FOR EACH ROW MODE DB2SQL
WHEN ( n.msgtype = 'RuntimeJobBegin' and n.jobcommand='PopBusView' )
BEGIN ATOMIC
insert into WIP.STEPS_START
values (n.msgbvname, n.msgbenumber, n.processname, n.msgtimestamp);
END$
|

 |

|
下载
| 描述 | 文件类型 | 文件大小 | 下载方法 | | DWC_WIP.zip | zip | 95KB | HTTP
|
作者简介  | |  | Cheung-Yuk Wu 在 IBM 里已经拥有超过 15 年的关系数据库工具和商业智能(Business Intelligence)应用程序开发经验,其中涉及到了 Windows 和 UNIX 平台上的 DB2、Oracle、Sybase、Microsoft SQL Server 和 Informix。她是 IBM DB2 Data Warehouse Center 和 Warehouse Manager 的架构师。她还开发了一些产品,包括 Tivoli for DB2、IBM Data Hub for UNIX 和 QMF。她也是 IBM San Jose Manufacturing Data Center 的一位 DBA for DB2, CICS and IMS。她在 San Luis Obispo 的 California Polytechnic State University 获得了计算机科学的学士学位。可以通过 wu@us.ibm.com
与 Cheung-Yuk 联系。
|
 | |  | Paul Wilms 在 IBM 从事分布式数据库和商业智能(Business Intelligence)方面的工作已经超过 20 年了。他已经撰写以及合写了几篇 与 IBM R* and Starburst 研究项目相关的研究论文。最近十年中,他为 IBM 全世界的客户提供商业智能和 ETL 工具方面的技术支持和咨询。Paul 还在美国和海外的会议中发表了很多演讲。他在法国的 National Polytechnic Institute of Grenoble 获得了计算机科学的博士学位。可以通过 dbwilms@us.ibm.com 与 Paul 联系。
|
对本文的评价
|  |