内容


InfoSphere Data Replication 用户自定义程序使用指南

Comments

概要

用户出口程序可以让用户在指定的表上自定义一组操作,IIDR 在复制数据过程中会执行这些操作。用户出口程序允许用户根据业务需求来定制环境。按照接口规范生成的用户出口程序,可以在 CDC 控制台中进行配置。

用户出口程序介绍

IIDR 提供了两种类型的用户出口:

  1. 存储过程

    这种类型的用户出口由数据库引擎直接运行,并且在处理数据库请求的时候速度会很快。这种类型的存储过程有特定格式,详情将在下文进行介绍。

  2. Java 类

    这种类型的用户出口使用 CDC JAVA API 来完成。CDC JAVA API 定义了用户出口的使用规范。用户可以通过阅读官方提供的接口文档来写出完整的程序。

按照运行级别,用户出口程序可以分为两类:

  1. 用户表和行操作的用户出口程序:

    这种类型的用户出口用来定制某个行操作的具体行为,可以定义在行操作之前或者之后

  2. 用户交易级别的用户出口程序:

    这种类型的用户出口用来定制某笔交易的具体行为,定义在 commit 操作之后。

    另外,IIDR 提供了大量的用户出口程序案例,供用户使用。用户可以扩展或者修改这些样本来适合自己的环境。

存储过程类型用户出口

定义存储过程类型的给用户出口,除了要遵守特定数据库类型的存储过程书写规范外,还需要遵循一定的 CDC 接口规范。在为 CDC 定义该存储过程时,规范如下:

存储过程用户出口必须至少具有两个参数,这两个参数必须按照下列顺序首先进行定义:

result : 整数类型的输出参数,如果存储过程出口运行成功,将返回整数值”0”;如果存储过程用户出口不成功,将返回非零值。

returnMsg : 字符输出参数,如果存储过程用户出口运行不成功,会将错误消息返回至 CDC 事件日志。

在缺省情况下,存储过程的用户出口程序和 CDC replication 使用同一共享连接作为连接至数据库的连接。共享同一连接可以确保 CDC Replication 和存储过程用户出口程序的数据是一致的,相互可以访问的。

在使用存储过程用户出口来检索数据时,可以通过使用 CDC 的系统参数来检索表中的数据。

目前可以检索到的数据以及方式如表 1 所示:

检索系统值 (s$前缀):使用 s$前缀可以检索到数据库中的系统值并应用于用户出口程序。例如:s$entry 标识了 CDC Replication 运行用户出口的入口点。

表 1. CDC 系统值

前缀和值数据类型描述
s$entry NUMBER 表示从中调用存储过程的入口点。您可以从下列入口点调用存储过程:
1
指示已经在表清除(截断)操作之前调用存储过程。
2
指示已经在表清除(截断)操作之后调用存储过程。
3
指示已经在行插入操作之前调用存储过程。
4
指示已经在行插入操作之后调用存储过程。
5
指示已经在行更新操作之前调用存储过程。
6
指示已经在行更新操作之后调用存储过程。
7
指示已经在行删除操作之前调用存储过程。
8
指示已经在行删除操作之后调用存储过程。
9
指示已经在表刷新操作之前调用存储过程。
10
指示已经在表刷新操作之后调用存储过程。
s$srcSysId VARCHAR 唯一地标识源数据的位置。
s$srcTabId VARCHAR 表示将复制的数据发送至目标的源数据库中源表的名称。
s$tgtTabId VARCHAR 表示从源接收复制的数据的目标数据库中目标表的名称。

检索日志控制字段(j$前缀):使用 j$前缀可以检索到数据库中的日志控制字段用于存储过程。例如 j$USER 标识了对源表进行更新的操作用户名。用于审计源表,将会非常有用。

表 2. 日志控制字段
前缀和值 数据类型 描述
j$CCID VARCHAR 标识使用插入、更新或删除操作的事务。
j$CODE VARCHAR 标识日志或记录条目的类型“U”(表示刷新操作)或“R”(表示镜像)。对于文件或表级条目,IBM® i 平台将发送“F”。
j$CTRR 或 j$CNTRRN VARCHAR 标识记录了日志/记录条目的源表的相对记录号。
注: 当在构成刷新的插入条目上调用存储过程时,CTRR 或 CNTRRN 包含有意义的信息。执行任何插入、更新或删除操作时,IBM i 平台也将填写此信息。
j$ENTT 或 j$ENTTYP VARCHAR 生成在源系统上标识操作类型的日志或记录代码。
j$JRN 或 j$JOURNAL VARCHAR InfoSphere CDC 正在从中读取插入、更新或删除操作的日志/记录的名称。
j$JOB VARCHAR 标识在源系统上进行插入、更新或删除的作业的名称。
j$MBR 或 j$MEMBER VARCHAR 标识源表的名称或其别名。
j$NBR 或 j$JOBNO VARCHAR 标识正在进行插入、更新或删除操作的源表上的程序的进程标识。
j$PGM 或 j$PROGRAM VARCHAR 标识源系统上进行插入、更新或删除操作的程序的名称。
j$SEQN 或 j$SEQNO VARCHAR 标识日志或记录中插入、更新或删除操作的序号。
j$SYNM 或 j$SYSTEM VARCHAR 标识源系统的主机名。
j$USER VARCHAR 标识在源上进行插入、更新或删除操作的操作系统用户名。
j$USPF VARCHAR 标识在源上进行插入、更新或删除操作的数据库用户名。
j$TSTP 或 j$TIMSTAMP VARCHAR 标识在源上进行插入、更新或删除操作或刷新的日期和时间。在支持微秒精度的环境中,此日志控制字段的日期和时间格式为 YYYY-MM-DD-HH:MM:SS.UUUUUU。否则,CDC Replication 将微秒组成部分 UUUUUU 设置为 0,或根本不将其包括在内。

检索数据值:根据参数的前缀,可以检索数据库中的数据,并应用于存储过程。例如,使用 b$来检索源列的前镜像,使用 k$来检索目标表中需要修改的行。

表 3. 检索数据前缀
前缀 方式 描述
b$<source column name> 输入 用于检索源列中数据的前映像。前映像是对其应用任何变换之前源表列中的初始映像。
例如,您可能已对源表进行下列更新:
UPDATE source_table
set MYCOLUMN = 2
where MYCOLUMN = 1;
这将对所有行设置 2,其中 MYCOLUMN 在您执行此 SQL 语句之前是 1。
当定义存储过程和决定要存储过程检索 MYCOLUMN 的前映像时,应指定下列项:
b$MYCOLUMN;
这将返回值 1。
a$<source column name> 输入 用于检索源列中数据的后映像。后映像是源表列中已转换的数据。例如,已派生的表达式转换的数据。
例如,您可能已对源表进行下列更新:
UPDATE source_table
set MYCOLUMN = 2
where MYCOLUMN = 1;
这将对所有行设置 2,其中 MYCOLUMN 在您执行此 SQL 语句之前是 1。
当定义存储过程和决定要存储过程检索 MYCOLUMN 的后映像时,应指定下列项:
a$MYCOLUMN;
这将返回值 2。
k$<target key column name> 输入 用于访问目标表以查找需要修改的行。
注: 键列不可供审计。
d$<target column name> 输入/输出 用于检索变换之后将用来更新目标数据库中的表的数据值。只有这些值可以被存储过程修改。

存储过程用户出口实例:软删除

在本例中,将会为读者展示如何使用存储过程用户出口程序实现软删除操作。本例中以 Oracle 数据源为例。

源表定义:create table BASIC.T1(ID int not null primary key,name char(200),address varchar(2000)).

软删除场景描述:当源端对表 BASIC.T1 进行删除操作时,目标表将不处理该操作,而是将目标表该记录的 ADDRESS 列标记为“DL”。

实现步骤如下:

  1. 创建 Oracle 存储过程用户出口程序:
    create or replace procedure SOFTDELETE 
     (
     	result out integer,
     	returnMsg out char,
     	b$ID in INTEGER,
     	b$NAME in char,
     	b$ADDRESS in varchar
     ) is
    begin
     update BASIC.T1 set ADDRESS='DL' where ID=b$ID and NAME=b$NAME and ADDRESS=b$ADDRESS;
     commit;
     result:=0;
     returnMsg:='ok';
    end SOFTDELETE;
  2. 在 CDC Managment Console 里配置该用户出口
    图 1. 配置存储过程用户出口
    图 1. 配置存储过程用户出口
    图 1. 配置存储过程用户出口
  3. 在 Table mapping 里标记 CDC replication 不要处理 Delete 操作,所有的 delete 操作将由用户出口来处理。
    图 2. 配置“Do Not Delete”
    图 2. 配置“Do Not  Delete”
    图 2. 配置“Do Not Delete”
  4. 软删除结果表示
    图 3. 软删除结果展示
    图 3. 软删除结果展示
    图 3. 软删除结果展示

Java 用户出口

JAVA 类型的用户出口的实现需要通过使用 CDC 提供的 Java API 接口来实现。JAVA API 的文档都放在 CDC 安装位置的 docs/api 目录下。CDC 产品提供了一系列的 JAVA 用户出口实例来帮助用户理解和使用这种类型的用户出口。所有的样本程序在 samples.jar 中找到。该文件位于 CDC 安装目录的 samples 目录下,提供的示例如下:

ArchiveLogPathUserExitSample.java:返回 Oracle 归档日志文件的标准路径(包括文件名和扩展名)。

CRUserExitSample.java:冲突解决用户出口,可与具有任何数据类型的主键列或任何数据类型的数字列的表一起使用。

DEUserExitSample.java:用于使用 %USERFUNC 列函数的表达式。它计算表达式中用户提供的参数的总和,并且返回以 1 为增量的总和。

SPUserExitSample.java:使用来自源的映像调用存储过程。

UserExitSample.java:预订复制事件以检索发生的事件的详细信息。

UserExitSample1.java:记录插入到目标上的表中的新行,并将它们存储在文本文件中。用户将文本文件的名称指定为参数。

使用这些实例之前需要对 java 源文件进行编译,生成可以运行的 class 文件。

编译及其使用方式如下:

  1. 停止 CDC Replication。
  2. 将 samples.jar 文件解压缩至 InfoSphere Data Replication 安装目录的 lib 目录中。确保在解压缩该 jar 文件时维持目录结构。在解压缩该 jar 文件后,您将具有类似以下的目录结构:
    <installation_directory>/lib/com/datamirror/ts/target/publication/userexit/sample
  3. 对样本用户出口进行更改。
  4. 编译已修改的用户出口。例如,如果要编译 UserExitSample.java,那么打开命令窗口,浏览到 lib 目录,然后发出下列命令:
    javac -classpath ts.jar:. com/datamirror/ts/target/publication/userexit/sample/UserExitSample.java
  5. 在成功运行命令后,浏览到下列目录并确认已创建 UserExitSample.class 文件:
    <installation_directory>/lib/com/datamirror/ts/target/publication/userexit/sample

    启动 CDC Replication。

  6. 配置用户出口的最后步骤是在 Management Console 中指定 UserExitSample 的标准路径。例如: com.datamirror.ts.target.publication.userexit.sample.UserExitSample

行级别用户出口的配置方式(JAVA 类)

行级别的 JAVA 用户出口程序需要表级别进行配置。CDC Replication Apply Engine 会对相关表上的用户出口进行初始化。例如,如果 Table 1 和 Table 2 都配置了用户出口 UE1, CDC 会为每个表创建独立用户出口,互相不影响使用。

一个完成 Java 用户出口包含三个方法,CDC Replication Apply Engine 会执行相应的方法来完成操作,这三个方法分别是:init(),processReplicationEvent(),finish()。

Init() 方法会被 CDC Apply Engine 在复制启动的时候执行,也就是在启动刷新或者镜像的时候,在任何数据被 Apply Engine 处理之前,该方法会被调用。通过这个方法,用户出口完成任何必须的初始化过程。

processReplicationEvent() 方法是用来处理 Apply Engine 接收到的任何变化数据的,例如在刷新或者镜像过程的变化数据。变化记录的完整的前镜像和后镜像都可以通过用户出口访问到。用户出口也可以获得目标数据来完成修改。

finish() 方法是在复制结束的时候执行的,也就是在刷新或者镜像结束的时候,来完成数据的复制工作。

JAVA 用户出口示例:在本实例中我们将会用 JAVA 的方式完成软删除的功能。

示例代码如清单 1:

清单 1. 软删除 Java 程序
import com.datamirror.ts.target.publication.userexit.DataTypeConversionException;
import com.datamirror.ts.target.publication.userexit.ReplicationEventIF;
import com.datamirror.ts.target.publication.userexit.DataRecordIF;
import com.datamirror.ts.target.publication.userexit.ReplicationEventPublisherIF;
import com.datamirror.ts.target.publication.userexit.ReplicationEventTypes;
public class UESoftDelete implements UserExitIF { …
 public void init(ReplicationEventPublisherIF publisher) throws UserExitException {
 // Process list of columns that will be updated on soft delete)
 }
 public boolean processReplicationEvent(ReplicationEventIF event) throws UserExitException {
DataRecordIF image = event.getBeforeData();
 //the first time UE is invoked for this table mapping, initialize SQL statements that will be executed
 //if the event is BEFORE-DELETE, update the row
 performUpdate(image);
 return true;
 }
 public void finish() {
 // perform any table specific cleanup such as closing the update statement
}

}

软删除用户出口程序会将要被物理删除的数据打个标记,而不进行真正的删除。如果要删除的目标记录不存在,会将该记录补充完整。同样需要在配置该用户出口时将删除操作禁止,配置该用户出口来处理删除操作。使用日志控制字段&ENTTYP 来标记删除操作。配置步骤如下:

  1. 在 CDC Management Console 里配置该用户出口,需要在删除操作发生之前激活该用户出口
    图 4. 配置 Java 用户出口
    图 4. 配置 Java 用户出口
    图 4. 配置 Java 用户出口
  2. 禁止 CDC 在目标的删除操作,由用户出口程序来处理删除操作
    图 5. 配置“Do Not Delete”
    图 5. 配置“Do Not  Delete”
    图 5. 配置“Do Not Delete”
  3. 在表映射里,将操作类型映射到目标字段
    图 6. 映射“操作类型”字段
    图 6. 映射“操作类型”字段
    图 6. 映射“操作类型”字段
  4. 复制记录的结果
    图 7. 软删除结果展示
    图 7. 软删除结果展示
    图 7. 软删除结果展示

交易级别用户出口的配置方式(JAVA 类)

交易级别的用户出口需要配置在订阅级别。在 CDC Management Console 里,右键单击订阅,选择 User Exit,来配置该类型的用户出口。CDC Apply Engine 会在订阅级别初始化该类型的用户出口。这种类型的用户出口同样包括三个方法:init(),processReplicationEvent(),finish()。在用户出口执行过程中,这三个方法会分别被 CDC Apply Engine 执行。

Init() 方法会被 CDC Apply Engine 在复制启动的时候执行,也就是在启动刷新或者镜像的时候,在任何数据被 Apply Engine 处理之前,该方法会被调用。通过这个方法,用户出口完成任何必须的初始化过程。

processReplicationEvent() 方法会在交易的边界被执行,也就是当 Apply Engine 捕捉到 commit 操作时。

finish() 方法是在复制结束的时候执行的,也就是在刷新或者镜像结束的时候,来完成数据的复制工作。

交易级别的用户出口应用也很广泛,例如用户可以将一个完整的交易写成 XML 格式的交易文件。或者将一个完整交易写入队列,如 Kafaka, MQ 等。

示例代码如清单 2 所示:

清单 2. 订阅级别用户出口
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import com.datamirror.ts.target.publication.userexit.*;
public class CDCTransactionFileWriter implements UserExitIF, SubscriptionUserExitIF {
/* init() is called once when the subscription is started and initializes the subscription context. Also, it 
 ensures that the processSubscriptionEvent method is invoked before every commit.*/
public void init(SubscriptionEventPublisherIF publisher) throws UserExitException {
…
}
public boolean processSubscriptionEvent(SubscriptionEventIF subscriptionEvent) throws UserExitException {
…
}
/* Table-level initialization is called once for every mapped table at subscription startup. It first retrieves the subscription context and then registers the events it wants to listen to. */
public void init(ReplicationEventPublisherIF eventPublisher) {
…
}
 /* Executed when table-level event is detected (insert/update/delete). This method writes an XML entry for the 
 table-level operation to the currently open output file. */
 public boolean processReplicationEvent(ReplicationEventIF replicationEvent) throws UserExitException {
 …
 }
}

总结

通过以上的介绍,读者可以学习到用户出口程序是 CDC 功能的重要扩展,通过使用用户出口程序,CDC 能够完成很多意想不到的功能。通过本文读者对 CDC 用户出口程序的原理,功能,类型,配置方式都会有很好的了解。希望读者学习本文能够独立完成对用户出口的编写和使用。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Information Management, Java technology
ArticleID=1036819
ArticleTitle=InfoSphere Data Replication 用户自定义程序使用指南
publish-date=09022016