@RANGE

使用 @RANGE 函数可以在两个或更多 Oracle GoldenGate 进程中划分任何表的行。它可以用来提高大型和大量访问的表的吞吐量,也可以用来将数据划分为集以分布到不同的目的地。在 TABLE 或 MAP 语句的 FILTER 子句中指定每个范围。

@RANGE 是安全且可扩展的。它通过保证同一处理组始终处理同一行来保持数据完整性。为了确保行不会将分区移到其他进程组,并且以正确的顺序执行 DML,在进程运行期间,基于 @RANGE 分区的列绝不能更改。对分区列的更新可能会导致“行未找到”错误或唯一约束条件错误。

@RANGE 计算输入中指定的列的散列值。如果未指定列,则使用 TABLE 或 MAP 语句的 KEYCOLS 子句来确定要散列的列(如果存在 KEYCOLS 子句)。否则,将使用主键列。

Oracle GoldenGate 会调整范围总数,以优化指定范围数的偶数分布。

由于可以为此函数指定任何列,因此具有相互关系约束条件的表中的行必须组合到同一进程或线索中,以保持引用完整性。

注:使用提取来计算范围比使用复制更高效。在目标端计算范围需要复制来读取整个线索,以查找符合每个范围规范的数据。

语法

@RANGE (<range>, <total_ranges> [, <column>] [, <column>] [, ...])

<range>

分配给指定进程或线索的范围。有效值为 1、2、3 等,最大值为 <total_ranges> 定义的值。

<total_ranges>

分配的范围总数。例如,要将数据分成三组,请使用值 3。

<column>

要作为范围分配基础的列的名称。此参数是可选的。如果未使用,Oracle GoldenGate 将根据表的主键分配范围。

您的数据不能包含缺失的列或 NULL 列;这将导致 @RANGE 函数异常终止。

列列表中指定的列必须存在于线索文件中。您可以在提取中使用 KEYCOLS 来控制此列,或者通过在提取中对该列使用 FETCHCOLS,或者确保该列是补充日志组的一部分,然后使用 LOGALLSUPCOLS。

示例

示例 1

在以下示例中,基于源 acct 表的 ID 列将复制工作负荷拆分为三个范围(在三个复制进程之间)。

(复制组 1 参数文件)

MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (1, 3, ID));

(复制组 2 参数文件)

MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (2, 3, ID));

(复制组 3 参数文件)

MAP sales.acct, TARGET sales.acct, FILTER (@RANGE (3, 3, ID));

示例 2

在以下示例中,一个“提取”处理将处理负荷拆分为两个线索。由于未定义用于范围计算的列,因此 Oracle GoldenGate 将使用主键列。

RMTTRAIL /ggs/dirdat/aa
TABLE fin.account, FILTER (@RANGE (1, 2));
RMTTRAIL /ggs/dirdat/bb
TABLE fin.account, FILTER (@RANGE (2, 2));

示例 3

在以下示例中,两个表具有基于 order_ID 列的相对操作。order_master 表的关键字为 order_ID,order_detail 表的关键字为 order_ID 和 item_number。由于关键字 order_ID 建立了相对性,因此在 @RANGE 过滤器中用于两个表以保留引用完整性。负载分为两个范围。

(参数文件 1)

MAP sales.order_master, TARGET sales.order_master,
FILTER (@RANGE (1, 2, order_ID));
MAP sales.order_detail, TARGET sales.order_detail,
FILTER (@RANGE (1, 2, order_ID));

(参数文件 2)

MAP sales.order_master, TARGET sales.order_master,
FILTER (@RANGE (2, 2, order_ID));
MAP sales.order_detail, TARGET sales.order_detail,
FILTER (@RANGE (2, 2, order_ID));