在本系列的第 1 部分中,我们简要概述了 IBM Information Server 产品套件中的 IBM InfoSphere DataStage 产品,解释了 Oracle Connector 阶段在 DataStage 作业中的作用。我们解释了阶段的指挥者进程 (conductor process) 与执行者进程 (player process) 之间的区别。我们介绍了并行性和分区的概念,解释了它们在 DataStage 环境和 Oracle 数据库环境中的含义的差异。我们详细介绍了为了在数据库上执行 SQL 语句而配置的 Oracle Connector 阶段的性能调优和疑难解答,这些语句包括用于在数据库中抓取和查找行的查询语句,以及用于在数据库中插入、更新和删除行的 DML 和 PL/SQL 语句。
在本系列的第 2 部分中,我们将继续介绍 Oracle Connector 性能调优。首先,我们将重点介绍连接器的批量加载模式的性能方面。在此模式下,连接器用于将数据加载到数据库中,在此过程中利用了 Oracle 直接路径接口。我们将介绍将记录加载到数据库中的操作,以及常常需要在加载记录之前和之后,在表索引和约束上执行的操作。我们然后将提供一些与结合使用拒绝链接和连接器相关的指南。我们将展示拒绝链接在一些情况下对连接器性能的影响,提供一些备用方法来满足您的考虑因素。在本文最后,我们将提供一些针对连接器中不同 Oracle ">数据类型的处理的性能调优策略。
与第 1 部分中一样,第 2 部分假设使用了 DataStage 并行作业和 Information Server Version 9.1,但提供的一些概念同样适用于 DataStage 服务器作业以及更早的 Information Server 版本。
批量加载
当 Oracle Connector 阶段被配置为在批量加载模式下运行时,它利用 Oracle 直接路径接口将数据写入目标数据库表。它从输入链接接收记录,并将其传递给 Oracle 数据库,该数据库将这些记录格式化为数据块并附加到目标表上,而不是将它们存储在现有块中的可用空闲空间中。要将该阶段配置为在批量加载模式下运行,必须将该阶段的 Write mode 属性设置为值 Bulk load。在这一节中,我们将介绍对调优该阶段中的批量加载操作性能具有重大影响的连接器属性和环境变量,如 图 1 所示。
图 1. 影响批量加载性能的连接器属性
与在 Insert 写入模式下运行相比,在 Bulk load 写入模式下运行该阶段通常会获得更高的性能。但是,Bulk load 写入模式引入了一些在使用Insert 写入模式时并不存在的限制,尤其是在并行执行模式下运行该阶段并将 Allow concurrent load sessions 连接器属性设置为值 Yes 时。这些限制主要与目标表上定义的触发器、索引和约束的处理相关。
本节剩余部分主要帮助您回答以下问题:
我应将该阶段配置为在 Bulk load 还是 Insert 写入模式下运行? 如果我选择在 Bulk load 写入模式下运行该阶段,那么我应如何配置该阶段中的剩余设置才能获得最佳性能?
数据量考虑因素
当决定将该阶段配置为 Bulk load 或 Insert 写入模式时,需要考虑的主要是数据量,换句话说,在该阶段中,在一次作业调用中平均会有多少记录写入目标表。
如果数据量相对较小,首选的选项是使用 Insert 写入模式,因为这种写入模式在维护目标表的索引、约束和触发器方面提供了更高的灵活性。在使用 Insert 写入模式时,所有表索引、约束和触发器都在作业执行期间执行,在作业完成后仍然有效。例如,如果在 Insert 写入模式下运行的阶段尝试向目标表插入一条记录,而该记录违反了该表中的主键约束,那么可以将该阶段配置为以多种方式处理此场景并继续处理剩余的记录,当该阶段在 Bulk load 写入模式下运行时,无法轻松采用这些方式。
它可定义并配置一个拒绝链接来处理违反约束的记录。每个违反表约束的输入记录都将路由到拒绝链接,您还可以可选地提供记录被拒原因的错误代码和消息文本。表中违反主键约束的现有行将保留在表中。 可以将它配置为在 Insert then update 写入模式下运行,此时会使用来自违反约束的记录的值来更新目标表中的现有行。 可以将它配置为在 Insert new rows only 写入模式下运行,此时会跳过(
忽略)违反约束的记录。 可以将它配置为包含 LOG ERRORS INTO 子句的 INSERT 语句,这会导致 Oracle 将违反约束的记录和错误信息一起重定向到指定的错误日志表。
如果数据量相对较大,并且主要目标是尽快将数据附加到目标表上,那么应考虑采用 Bulk load 模式。
此处的问题是,应将多大的数据量视为小数据量或大数据量。这一决定取决于其他一些因素,比如您在选择 Insert 写入模式时希望牺牲多少性能,这取决于将数据推送到数据库的批次窗口大小和可用的系统资源。根据经验,数千个记录会被视为小数据量,而数百万个记录应可能被视为大数据量。
如果表没有定义任何索引、约束和触发器,那么 Bulk load 写入模式会是一个不错的选项,无论涉及的数量有多大,因为这种写入模式带来的许多限制不再适用。这包括以下场景:表并没有定义索引、约束和触发器,但您拥有一些过程,可在加载数据之前禁用或丢弃它们,然后在加载完成后启用或重新构建它们。
以下这个简单的测试可帮助您确定选择哪种写入模式:
设计一个测试作业,它的 Oracle Connector 阶段有一个输入链接。在测试作业中,提供与将由生产环境中的实际作业处理的记录具有类似的数据量和结构的记录。 确保测试作业中使用的目标数据库表拥有与将在生产环境中使用的表相同的定义。如果生产作业对数据库中的一个现有表执行增量数据加载,请确保用于测试作业的表最初填入了与将在生产环境中使用的表类似的行数。 在插入模式下运行该作业多次,记录完成该作业所用的平均时间。 手动禁用目标表上的任何索引、约束和触发器,对配置为批量加载写入模式的连接器阶段重复执行该作业多次,记录完成该作业所花费的平均时间。 对比前两组作业运行的结果。如果得到的数字类似,则表明 Insert 写入模式就足够用。如果批量加载完成得
更快,则确定需要在表上执行哪些额外操作来还原约束和索引。从某个工具(比如 SQL*Plus)发出这些操作,查看它们花费了多少时间来完成这些操作。如果该时间与批量加载数据所花费的总时间量明显少于插入数据所花费的时间,那么批量加载模式可能是更好的选择。
处理触发器
如果目标表拥有需要为写入表的每个行触发的触发器,则不应该使用批量加载模式,因为此模式不支持数据库触发器。要将数据批量加载到拥有触发器的表中,需要在加载前禁用触发器。该连接器提供了一个选项,能够在加载之前自动禁用触发器,并在加载之后启用它们。启用触发器后,它们仅为该时刻之后插入表的行而触发。它们不会为禁用触发器期间加载的行而触发。
处理索引
如果表拥有索引,可将该阶段配置为在执行加载时禁用所有索引。为此,可以将 Index maintenance 连接器属性设置为值 Skip all。这通常是最好的选择,因为它运行您没有限制地在并行执行模式下运行该阶段,使用在输入链接的 Partitioning 页面上选择的任何 Partition type 值。但是,所有索引都会在加载完成后标记为 UNUSABLE 并应重新构建。在这里,数据量和索引数量发挥着关键的作用。如果增量地加载对表中已存在的记录数而言相对少量的记录,在 Insert 写入模式下运行该阶段可能快得多,而且会让数据库在整个插入操作中维护索引,无需在批量加载后重构所有索引。另一方面,如果目标表是空的,而且需要向其中加入大量记录,那么使用 Bulk load 写入模式可能更合适,因为需要在所有行上构建索引,而且在这种情况下,第一次加载所有记录时不维护索引,然后从头构建索引,这样做会更快一些。
无需在加载记录之后用外部工具重新构建索引,可以将该阶段配置为从 Oracle 数据库请求在加载期间维护索引,方法是将 Index maintenance选项属性设置为 Do not skip unusable 或 Skip unusable。这两个选项的使用具有很高的限制性,而且在大多数情况下不是最佳选择。如果考虑使用这两个选项之一,则需要牢记以下事项:
需要将 Allow concurrent load sessions 连接器属性设置为 No,否则在加载任何数据之前会获得 Oracle 错误 “ORA-26002: Table string has index defined upon it”。这项要求表明您无法在并行执行模式下运行该阶段,除了将数据加载到某个分区表中的特殊情况,本文 后面 介绍如何将记录加载到分区表中的小节中将会介绍这种特殊情况。 如果表有一个 UNIQUE 索引,该索引将在作业完成之后保持 VALID,但这种情况只出站在加载的所有行都未违反索引所要求的惟一性时。否则,索引会自动标记为 UNUSABLE,即使作业已经成功完成。对运行该作业的后续尝试将会失败,报告的 Oracle 错误取决于 Index maintenance option 属性值。对于 Do not skip unusable 值,错误将是 “ORA-26028: index string.string initially in unusable state”,对于 Skip unusable 值,错误将是 “ORA-26026: unique index string.string initially in unusable state”。 如果表中包含一个 NON-UNIQUE 索引,那么该索引会在加载之后保持 VALID。如果该索引在加载之前被标记为 UNUSABLE,那么该行为将取决于 Index maintenance option 属性值。对于 Do not skip unusable 值,该索引会导致 Oracle 错误 “ORA-26002: Table string has index defined upon it”,对于 Skip unusable 值,该作业将完成,索引将保持 UNUSABLE 状态。
您可以将阶段配置为在加载之后自动重新构建索引,可控制索引重新构建语句的 LOGGING 和 PARALLEL 子句,以便优化索引重新构建过程。您可以将阶段配置为在出现任何索引重新构建语句失败时让作业失败,或者仅发出警告消息。为了提升性能,连接器阶段仅在必要时才重新构建索引。它将在重新构建每个索引之前检查它的状态。如果索引被标记为 VALID,那么连接器将会跳过它。这同样适用于本地和全局分区的索引。在这种情况下,连接器将检查索引分区和子分区(如果索引是本地分区的且表是复合分区的),仅重新构建标记为 UNUSABLE 的索引分区和子分区。