Oracle Golden Gate Setup And Solutions

GoldenGate安装部署及解决方案

周炯
http://www.itpub.net/thread-1637192-1-1.html

1、GoldenGate 简介

GoldenGate软件是一种基于日志的结构化数据复制软件,它通过解析源数据库在线日志或归档日志获得数据的增删改变化,再将这些变化应用到目标数据库,实现源数据库与目标数据库实时同步(real-time data synchronize)、双活(active-active high availability)。GoldenGate软件可以在异构的IT基础结构(包括几乎所有常用操作系统平台和数据库平台)之间实现大量数据亚秒一级的实时复制,其复制过程简图如下:

如上图所示,GoldenGate的数据复制过程如下:

利用捕捉进程(Capture Process)在源系统端读取Online Redo Log或Archive Log,然后进行解析,只提取其中数据的变化如增、删、改操作,并将相关信息转换为GoldenGate自定义的中间格式存放在队列文件(trail)中。再利用传送进程将队列文件通过TCP/IP传送到目标系统。捕捉进程在每次读完log中的数据变化并在数据传送到目标系统后,会写检查点(checkpoint),记录当前完成捕捉的log位置,检查点的存在可以使捕捉进程在中止并恢复后可从检查点位置继续复制;

目标系统接受数据变化并缓存到GoldenGate队列当中,队列为一系列临时存储数据变化的文件,等待投递进程读取数据;

GoldenGate投递进程从队列中读取数据变化并创建对应的SQL语句,通过数据库的本地接口执行,提交到数据库成功后更新自己的检查点,记录已经完成复制的位置,数据的复制过程最终完成。

由此可见,GoldenGate是一种基于软件的数据复制方式,它从数据库的日志解析数据的变化(数据量只有日志的四分之一左右)。GoldenGate将数据变化转化为自己的格式,直接通过TCP/IP网络传输,无需依赖于数据库自身的传递方式,而且可以通过高达9:1的压缩率对数据进行压缩,可以大大降低带宽需求。在目标端,GoldenGate可以通过交易重组、分批加载等技术手段大大加快数据投递的速度和效率,降低目标系统的资源占用,可以在亚秒级实现大量数据的复制,并且目标端数据库是活动的
GoldenGate提供了灵活的应用方案,基于其先进、灵活的技术架构可以根据用户需求组成各种拓扑结构,如图所示:

GoldenGate可以提供可靠的数据复制,主要体现在下面三点:
(1)保证事务一致性
GoldenGate在灾备数据库应用复制数据库交易的顺序与在生产中心数据库上的顺序相同,并且按照相同的事务环境提交,确保在目标系统上数据的完整性和读一致性,为实时查询和事务处理创造了条件。 
(2)检查点机制保障数据无丢失
GoldenGate的抽取和复制进程使用检查点机制记录完成复制的位置。对于抽取进程,其检查点记录当前已经抽取日志的位置和写队列文件的位置;对于投递进程,其检查点记录当前读取队列文件的位置。检查点机制可以保证在系统、网络或GoldenGate进程故障重启后数据无丢失。
(3)可靠的数据传输机制
GoldenGate用应答机制传输交易数据,只有在得到确认消息后才认为数据传输完成,否则将自动重新传输数据,从而保证了抽取出的所有数据都能发送到备份端。数据传输过程中支持128位加密和数据压缩功能。

Oracle 公司的GoldenGate产品,可以在异构的IT基础结构之间实现大量数据的秒一级的数据捕捉、转换和投递。目前最新版本为V11.1.1.1.0。
GoldenGate可以支持几乎所有常用操作系统如和数据库平台,如下表所示:

操作系统 数据库
MS NT, 2000, XP, Linux, Sun Solaris, HP-UX, IBM AIX, HP NonStop, TRU64, IBM z/OS,OS/390 Oracle, DB2, MS SQL Server, MySQL, Enscribe, SQL/MP, SQL/MX, Sybase, Teradata, 其他ODBC 兼容数据库

2、文档约定和说明
为统一表示命令和便于查看,对格式作如下约定:
GG_HOME> 表示从操作系统命令行(cmd)进入GoldenGate安装路径下执行命令。
GGSCI> 表示在GoldenGate命令环境中执行命令。
SQL> 表示在数据库下执行SQL语句
/*
*/ 表示配置文件内容,/***不包含在内。
< > 表示自定义参数,如自定义表名<tablename>

以下示例中若无特殊说明,GoldenGate使用的版本主要为11.1,部分使用10.4版本,除部分新特性,两者基本无差别;GoldenGate命令行中的操作均是在mgr主进程running时进行,当然,GoldenGate安装部分除外。

补充说明:
该文档主要介绍GoldenGate基本使用、GoldenGate的各类解决方案,以及以往本人在使用测试中总结的经验,文中的例子和执行的命令都是参照官方文档并亲自测试执行过。但因个人能力所限,错漏之处再所难免,文档中也不可能覆盖GoldenGate的方方面面。而且,因为GoldenGate本身提供了大量的参数,也不可能在这里一一列举,本文档中只举例了常用的一些参数命令,关于各个参数的具体使用语法和作用,还请参照官方文档《Oracle GoldeGate Reference Guide》。

3、GoldenGate软件安装
在不同的操作系统和平台上安装GoldenGate,需要在官网下载对应的版本。32位系统和64位系统的安装介质虽然不同,但是在同一OS上安装方式是一样的。
GoldenGate需要解析数据库的日志文件,所以安装位置必须要能访问到日志文件(在线日志和归档文件),并具有相应的权限。

3.1 GoldenGate软件安装包下载
经常有人问我GoldenGate的下载地址,所以在这里专门说明一下。
GoldenGate软件的官方下载地址:http://edelivery.oracle.com/ 目前只有这个地址能下到对应32位操作系统的安装介质。
首页如下:

网页开头点击这个Continue进入下载。
首次进入需要登记一些个人信息,如名字、公司等,然后下方选择同意协议之类的,点Continue进入搜索。
搜索时如下选择:

点GO,然后选择对应版本的Oracle GoldenGate下载。GoldenGate安装包一般只有几十兆的大小,下载还是很快的。

GoldenGate除了同步软件这块,还有其他相关的产品,比如Oracle GoldenGate Director,用于集中图形化管理和监控;Oracle GoldenGate Veridata,用于两端同步数据质量检验。在本文档中暂不介绍。

3.2 Windows下安装
(1)安装Microsoft Visual C ++ 2005 SP1
Windows操作系统需要首先下载安装Microsoft Visual C ++ 2005 SP1发行包(注意该软件也分32位和64位)。

(2)绿色安装GoldenGate
下载对应平台版本的GoldenGate安装包,解压。然后进入操作系统命令行(cmd),进入GoldenGate解压路径下,执行:
GG_HOME >ggsci — 进入GoldenGate命令窗口模式
GGSCI> CREATE SUBDIRS — 建立子目录
GGSCI>edit param mgr — 配置GoldenGate主进程参数
由于第一次执行该命令,会提示创建mgr参数文件,点“是”并在文本中输入如下参数:
/*
PORT 7801 — GoldenGate主进程端口号
DYNAMICPORTLIST 7802-7820 — GoldenGate为进程间通讯动态分配的端口段,注意这里如果分配的端口端少于extract-replicat进程对的话,会导致部分进程因通讯失败而出错。
*/
保存,生成的参数文件保存在GG_HOME\ dirprm下
然后可以启动GoldenGate主控制进程:
GGSCI>start mgr
GGSCI>info all — 查看进程状态
如果进程MANAGER状态显示为RUNNING则表示主进程已在运行。至此软件安装完成。

(3)管理GoldenGate服务
在WINDOWS下还可以将GoldenGate主进程作为系统服务进行管理,如下配置:
GGSCI> edit param ./globals — 配置全局参数,注意前面的 ./ 表明与其他参数文件位置不同,该参数文件是直接位于GoldenGate安装路径下的
输入:
/*
MGRSERVNAME <name> — GoldenGate主进程端口号,<name>为自定义的系统服务名
*/

然后退出GGSCI命令行:GGSCI> exit
GG_HOME > install addservice addevents — 创建服务,完成后可以直接进服务进行管理

WINDOWS删除GoldenGate服务:
GG_HOME > install deleteevents deleteservice — 对应删除服务操作
或者在注册表删除:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 一般服务会以相同的名字在这里显示一个主健,直接删除相关的键值便可

3.3 Linux和Unix下安装
(1)检查必需的lib包
下载对应平台版本的GoldenGate,解压。在解压路径下执行:
[root@GG_HOME] > # ldd ggsci
将列出所有需要的lib和当前缺少的。GoldenGate在Linux和Unix下安装,需要安装ORACLE的lib环境以及$ORACLE_HOME/lib下的几个包,所以必须安装在Oracle之后,而且确保在环境变量中加入:
export LD_LIBRARY_PATH=$ORACLE_HOME/lib

(2)绿色安装GoldenGate
在解压路径下执行./ggsci进行接口命令行,
[root@GG_HOME] > # ./ggsci — 进入GoldenGate命令窗口模式
GGSCI> CREATE SUBDIRS — 建立子目录
GGSCI>edit param mgr — 配置GoldenGate主进程参数
由于第一次执行该命令,会提示创建mgr参数文件,点“是”并在文本中输入如下参数:
/*
PORT 7801 — GoldenGate主进程端口号
DYNAMICPORTLIST 7802-7820 — GoldenGate为进程间通讯动态分配的端口段,注意这里如果分配的端口端少于extract-replicat进程对的话,会导致部分进程因通讯失败而出错。
*/
保存,生成的参数文件保存在GG_HOME\ dirprm下
然后可以启动GoldenGate主控制进程:
GGSCI>start mgr
GGSCI>info all — 查看进程状态
如果进程MANAGER状态显示为RUNNING则表示主进程已在运行。至此软件安装完成。

和Windows下安装的主要区别是需要确认必需的lib包,进入GGSCI接口命令行后的操作都是一致的。

4、GoldenGate同步基本配置
GoldenGate支持目前大部分主流数据库,这也是它的优势之一。下面列举了Oracle、Db2、Sybase之间的同步。

同步测试的准备工作中,有一部分是共通的,如下:
(1) 在源端和目标端建立相同结构的两个表,建立主键。保证复制的对象在一开始是一致的。
(2) 保证没有相关对象的触发器(会导致数据冲突的那些)或设置失效。
(3) 数据库需要开启必须的日志模式。不同数据库的配置差异主要在这一步。
(4) 源端和目标端都需要安装相应版本的GoldenGate软件,并分配一个有DBA权限的数据库用户给GoldenGate用以连接数据库。
备注:分配给GoldenGate的用户一般情况下并不需要完全的DBA权限,在官方文档上有详细的权限需求说明,但是完全按照那个配置比较繁琐。额外的,如果数据库使用ASM时,需要sysdba权限。

4.1 oracle之间同步和GoldenGate基础

4.1.1 Oracle数据库设置
首先安装好ORACLE,设置好ORACLE_SID,ORACLE_HOME等环境变量。当然,推荐的做法是在每个进程配置文件里都加上指定的环境变量参数,在后面优化配置中进行说明。
Oracle数据库需要开启归档日志,并开启最小附加日志模式。
SQL> select supplemental_log_data_min from v$database; — 查看是否开启了最小附加日志模式
SQL> alter database add supplemental log data; — 开启最小附加日志模式

实际生产应用中,最好同时打开ORACLE的强制日志模式,以防止源数据库因直接路径加载忽略redo生成而导致这部分数据无法同步:
SQL> select force_logging from v$database;
SQL> Alter database force logging;

光开启最小附加日志模式还不够,还需要打开表级的补全日志,可以在GoldenGate中使用add trandata命令强制重做日志记录主键值,以保证在目标端能成功复制:
GGSCI> dblogin userid ddw,password ddw — GoldenGate中登录OARCLE数据库
GGSCI>add trandata ddw.<tablename> — 表名可以使用通配符
GGSCI> add trandata coss3.per_test,nokey,cols(sampletime, objectid)
— 无主键指定字段补全的示例
也可以在数据库中打开:
SQL> alter table <tablename> add supplemental log data (primary key) columns;

千万不要小看这步日志设置,其实在GoldenGate的配置中,这步是最容易出错的环节。如果开启DDL复制做冗灾备份,最好直接在数据库级别打开补全日志:
SQL> alter database add supplemental log data (primary key,unique,foreign key) columns;
检查一下,全是YES就OK了(整个数据库级别补全)
SQL> select supplemental_log_data_min,
supplemental_log_data_pk,supplemental_log_data_ui
from v$database;

4.1.2关于Oracle补全日志补充说明
Oracle日志(redo log)一般用于实例恢复和介质恢复,但是如果需要靠日志还原完整的DML操作信息(比如Logmnr、Streams和这里的Goldengate),默认记录的日志量还不够。比如一个UPDATE的操作,默认redo只记录了rowid以及被修改的字段信息,但这里GoldenGate还原这个事务,因为不是根据rowid而是SQL层面根据唯一键值来定位记录,所以还需要将主键或者其他字段的信息附加到日志中去。要往日志中增加这些额外字段信息的操作,就是开启补全日志,即Add Supplemental Logging。打开补全日志,会使数据库的日志量增加,所以只打开需要的级别和对象即可。
Oracle补全日志可以在数据库级别设置,也可以在表级别设置。在数据库级别中,补全日志按补全的信息量,对应好几个级别:
(1) 最小附加日志(Minimal supplemental logging):是开启logmnr的最低日志要求,提供了行链接(chained rows)和多种数据存储(比如聚簇表、索引组织表)的信息。在Oracle 9.2之后的版本中,默认都不开启。
(2) 主键补全(Primary key supplemental logging):在日志中补全所有主键列。如果表中无主键,则补全一个非空唯一索引列;如果非空唯一索引键也没,那么会补全除了LOB和LONG类型字段以外的所有列,这时就和下面的所有补全一样了。
(3) 唯一键补全(Unique key supplemental logging):当唯一键列或位图索引列被修改时,在日志中补全所有唯一键列或位图索引列。打开唯一键补全也会同时打开主键补全。注意这个级别是需要条件触发的。
(4) 外键补全(Foreign Key supplemental logging):当外键列被修改时,将在日志中补全所有外键列。这个级别也是需要条件触发的。
(5) 所有补全(All supplemental logging):在日志中补全所有字段(排除LOB和LONG类型)。

这里对于补全日志的详细操作语句不做一一说明。

数据库级别中的5个类型中,除了最小附加日志级别,都可以在表级进行设置。除此之外,表级还可以明确指定需要补全的列。
Oracle表级补全日志需要在最小补全日志打开的情况下才起作用,即若一个数据库没有开最小补全日志或之前drop supplemental log data操作则即便指定了表级补全日志,实际在重做日志输出的过程中描述的记录仍只记录rowid和相关列值。而要关闭最小补全日志,也必须首先关闭数据库级别的其他补全级别后,才能关闭。
所以在GoldenGate中,对于Oracle数据库的日志补全要求,至少是打开最小附加日志和主键补全。主键补全只要在需要同步的表上开启即可。当然GoldenGate的add trandata语法中也可以指定补全的列,这和Oracle表级补全日志的功能完全一致。毕竟,日志还是由数据库生成的,GoldenGate并不能直接控制日志的生成方式和规则,只能根据所捕获的数据库的日志规则而来。不同的数据库,日志补全的规则也会不同。

以上部分内容参考自《Oracle 10gR2 Utilities》Supplemental Logging部分

4.1.3 dml同步
4.1.3.1 一对一的实时同步简单配置

同步流程如图:

(1)源数据库端添加提取进程(extract process)

GGSCI> add extract extl,tranlog,begin now — 新增抽取进程extl,基于日志方式,立即生效
需要注意的是,GoldenGate中的进程名最长只能8个字符。
注意,如果是在RAC环境下,需要再加上THREADS <n>指定提取的日志THREAD
GGSCI> add extract extl,tranlog,begin now , THREADS <n>

GGSCI> edit param extl — 生成并编辑同名配置文件
/*
extract extl — 抽取进程名
userid ddw@orcl,password ddw — 连接本机DB的帐号密码
rmthost 192.168.0.44, mgrport 7801 — 目标数据库服务器地址和GG服务端口号
rmttrail d:\tools\GG\gg10g\dirdat\rl — 远程队列的位置(下一步建的东西)
dynamicresolution — 优化参数,动态分析表结构
gettruncates — 抓取truncate数据
table ddw.aatest; — 需要抽取的表,可以使用通配符
*/
然后给这个提取进程创建远端队列,即图中的RMTTRAIL:
GGSCI> add rmttrail d:\tools\GG\gg10g\dirdat\rl extract extl

需要注意的是,这里最后的名称rl(可以自定义,字母或数字)是指以后生成的trail文件都会以rl开头,如rl000001,这个文件头名称最长只能2个字符。如果需要在文件级别区分队列,建议将队列创建于于不同的目录下。

开启这个提取进程:
GGSCI> start extl
GGSCI> info all — 查看所有进程状态
此时extl进程running则表示已成功运行,这时开始会在前面指定的目标端队列位置生成trail文件。如果进程出错,可以使用view report extl 查看错误信息。

(2)目标数据库端添加复制应用进程(replicat process)

在目标端GoldenGate命令行中配置复制进程:
GGSCI>add replicat repl exttrail d:\tools\GG\gg10g\dirdat\rl,begin now,nodbcheckpoint –新增复制进程,使用对应的队列rl,即刻开始,使用文件检查点
GGSCI>edit param repl — 配置复制进程参数
/*
replicat repl — 复制进程名
userid ddw@orcl,password ddw — 目标数据库的帐号密码
assumetargetdefs — 两台数据库数据结构一致则使用此参数
reperror default,discard — 如果复制数据出错则忽略
discardfile D:\repsz.dsc,append,megabytes 100 — 错误信息写入XXXX文件,追加模式,最大100m
gettruncates — 复制truncate操作
map ddw.aatest, target ddw.aatest_1; — 映射关系,注意target前必须留一个空格
— map ddw.aatest, target ddw.aatest_1, keycols (name), where (TYPE1 = "1")
— 加两横杠在配置文件中进行注释;keycols指定唯一键;where筛选数据
*/
开启复制进程:
GGSCI>start repl

至此,一个最简单的同步配置完成,对于源数据库相应表的insert,update,delete和truncate操作都将通过日志捕获并同步到目标数据库。

4.1.3.2 使用datapump

加入datapump后的数据传输的流程:

这里的datapump与ORACLE 10g推出的数据泵不是一个概念。在GoldenGate中,datapump相当于一个次级提取进程(secondary extract)。在上面演示的同步流程中,提取进程直接将提取的redo信息经过处理后放置到了目标端服务器上,当两者之间的网络出现故障时,会因无法生成trail文件而导致提取进程崩溃,错误提示类似如下:
2010-11-12 10:01:21 GGS ERROR 150 TCP/IP error 10061 (由于目标机器积极拒绝,无法连接。); retries exceeded.
2010-11-12 10:01:21 GGS ERROR 190 PROCESS ABENDING.

而加入datapump后,主提取进程(即第一个extract)首先将trail生成在本地,然后datapump读取本地trail再发送到目标服务器,即便网络故障,主提取进程仍然能随着事务生成trail文件,而datapump则会暂时停止传输,等待网络通畅后在将堆积的本地trail文件发送至目标服务器,从而实现了断点传输的功能。在实际应用中,每一个同步流程都应该配置datapump以应对网络问题。

加入datapump的配置:
将前面extl参数文件中的
/*
rmthost 192.168.0.44, mgrport 7801
rmttrail d:\tools\GG\gg10g\dirdat\rl
*/
替换为
/*
exttrail d:\tools\GG\gg10g\dirdat\l1 — 本地队列文件生成位置
*/

配置datapump进程:
GGSCI> ADD EXTRACT pump1, EXTTRAILSOURCE <local_trail>, BEGIN <time>
— <local_trail>即是对应extl配置文件中定义的d:\tools\GG\gg10g\dirdat\l1
GGSCI> edit param pump1
/*
extract pump1
userid ddw, password ddw
rmthost 192.168.0.44, mgrport 7801
rmttrail d:\tools\GG\gg10g\dirdat\r1
PASSTHRU|NOPASSTHRU — 直通模式或普通模式
gettruncates
table ddw.bbtest;
*/
直通模式用在两边表名、列名一致,可以直接映射的情况,不需要额外配置;普通模式可以配置表名列名自定义映射,可以加FILTER、transformation等,需要配置一个数据定义文件(data-definitions file)。

然后修改原先为提取进程配置远端队列位置:
GGSCI> delete rmttrail d:\tools\GG\gg10g\dirdat\rl extract extl
GGSCI> add rmttrail d:\tools\GG\gg10g\dirdat\rl extract pump1
然后启动extl和pump进程就OK了。

4.1.3.3 使用数据定义文件
GoldenGate数据定义文件(data-definitions file),主要用于不同数据源之间(比如下面的Oracle与DB2之间的同步),进行数据同步时用来转换数据格式。数据定义文件主要包含表名、字段名、字段类型、字段长度和偏移量。
利用GoldenGate的defgen工具生成一个数据定义文件(data-definitions file),大致步骤如下:
(1)创建DEFGEN工具的参数文件
(2)运行DEFGEN工具生成数据定义文件
(3)配置GG进程识别定义文件

例子:
GGSCI> edit param defgen — 创建DEFGEN工具的参数文件
/*
DEFSFILE <full_pathname> — 指定由DEFGEN生成的数据定义文件的全路径和名称
[{SOURCEDB | TARGETDB} <dsn>,] — oracle不需要配置这个参数
[USERID <user>[,PASSWORD <password>]] — DB2不需要配置PASSWORD
TABLE <owner>.<table> — 分析指定表生成配置文件
*/
类似如下(ORACLE):
/*
DEFSFILE GG_HOME\dirdef\extdb.ref
USERID ddw,PASSWORD ddw
TABLE ddw.aatest;
*/
然后退出GGSCI,在GG安装路径下运行DEFGEN工具:
GG_HOME > defgen paramfile dirprm/defgen.prm
配置文件默认生成在GG_HOME\dirdef下,不要去手动修改。如果对应表的表结构发生更改,需要重新生成这个配置文件。
然后将生成的配置文件拷贝至目标服务器的GG_HOME\dirdef下。修改复制进程repl参数文件:
GGSCI>edit param repl
将原先的assumetargetdefs参数替换为sourcedefs GG_HOME\ dirdef\extdb.ref
GGSCI>stop repl
GGSCI>start repl
数据定义文件的配置完成。

4.1.3.4 配置进程检查点(checkpoint)
检查点记录了进程读写的位置信息用以数据恢复,目的是为了防止进程因系统、网络崩溃而导致的数据丢失,对于GoldenGate保证数据同步过程中数据不丢失非常重要。GoldenGate的检查点由一个内部进程自动控制,与数据库检查点的概念类似。提取进程的检查点记录它在数据源中的读取位置和队列的写出位置,复制进程的检查点记录它读取队列的位置。每条提取或复制进程都有自己对应的检查点信息。当GoldenGate的进程重启时,由它所记录的检查点决定需要读取的队列位置。
GoldenGate的检查点信息有两种存放方式:
(1)默认存放在GGHOME\dirchk下的文件中,一个进程对应一个文件。提取进程只能使用这种模式。不需要特殊配置。
(2)存放在数据库指定的表中,需要进行如下配置:
首先在./globals参数文件中加入:
/*
CHECKPOINTTABLE [<owner>.<table>] — 指定的检查点记录表
*/
然后运行:
GGSCI> DBLOGIN [SOURCEDB <dsn>][, USERID <db_user>[, PASSWORD <pw>]]
GGSCI> ADD CHECKPOINTTABLE [<owner>.<table>] — 生成这个检查点记录表
在新增复制进程时可以在添加时指定checkpointtable [<owner>.<table>]替代nodbcheckpoint,使用数据库记录检查点信息。

ORACLE官方文档中,比较推荐将复制进程的检查点信息存放到数据库表中进行管理,认为在某些情况下能促进数据恢复。并指出检查点信息量非常小,而且是进行记录更新而非记录插入,一个进程只对应一条记录,在它特殊的检查点处理机制下不会对数据库造成影响。个人猜想是当目标数据库崩溃还原后(特别是在不完全恢复的情况下),检查点信息能同数据库一起还原,在数据上能利用数据库事务性与数据库保持一致,从而在数据库正常打开后能继续进行数据同步。但实际上并不必要,因为数据库故障的情况多种多样,就算检查点同步恢复后,也不能保证直接就能启动GoldenGate进程。

4.1.3 ddl同步

GoldenGate的DDL同步只支持两边一致的数据库,限制条件较多(如不能进行字段映射、转换等),具体可以参考官方文档。DDL的抓取不是通过日志抓取来捕获的,而是通过触发器来实现,所以对源数据库的性能影响要比单纯的数据抓取要大很多,可谓屏弃了GoldenGate的优势。尽量不要使用GoldenGate的DDL复制功能,在大多数业务系统中,实际上不会有频繁的数据库结构变动,完全可以通过手工的方式进行维护。确实有大量DDL操作的环境,如果可以,还是推荐物理DG之类的替换方案;确实要使用GoldenGate的DDL复制,那么请详细参考官方文档的限制和说明。
— 以上主要为个人意见,有不同看法的请无视

开启DDL复制的基本配置步骤为:
(1)关闭ORACLE的回收站功能。
(2)选择一个数据库schema存放支持DDL的GoldenGate对象,运行相应创建脚本。
(3)编辑globals参数文件。
(4)修改extl和repl的配置文件

具体操作步骤:
(1)关闭数据库回收站:
SQL>alter system set recyclebin=off scope=both;

(2)编辑globals参数文件:
GGSCI>edit param ./globals
添加以下内容后保存:
GGSCHEMA ddw — 标明支持DDL的GG对象存放在哪个schema下

(3)执行创建脚本:
首先需要命令行进入GG安装目录下,然后再运行sqlplus执行脚本,如果不进入目录下脚本执行会报错(应该是由于GG脚本中子脚本嵌套使用相对路径的问题所造成)。
SQL>@marker_setup.sql — 提示输入目标schema
SQL>@ddl_setup.sql — 提示输入目标schema,输入initialsetup最后输入yes
SQL>@role_setup.sql
SQL>grant GGS_GGSUSER_ROLE to ddw; — 不进行该步赋权后面起进程会报错
SQL>@ddl_enable.sql — 使触发器生效

(4)修改提取进程和复制进程的配置文件,分别加入ddl include all属性。
此时repl必须指定assumetargetdefs属性,这表明只有两边数据库结构一致的情况下才可以启用DDL复制。另外,开启DDL同步不能再只映射单表了,对整个模式下的对象都有效。
加入DDL复制之后,数据复制的lag明显增加了。

清除数据库中DDL复制的设置
在实际测试中,由于我在同一个数据库中进行映射,映射表结构不一致,导致进程报了一系列的错误。这个时候需要把通过脚本创建的GG对象中的数据清空,安装目录下只提供了清除对象的脚本,可以如下操作:
首先要求把所有的GG进程停掉,包括mgr进程
SQL>@ddl_disable.sql — 首先使DDL触发器失效
SQL>@ddl_remove.sql
SQL>@marker_remove.sql
role_setup.sql没有对应的清除脚本,但是这块不影响配置信息的清除
然后重新再创建脚本。

4.2 oracle与db2同步

设置DB2数据库参数:
db2 connect to <database> user <username> using <password> — DB2命令行工具登陆DB2
db2 get db cfg for <database name> — 查看数据库参数配置
db2 update db cfg for <database name> using LOGRETAIN ON — 设置LOGRETAIN参数
db2 update db cfg for <database name> using USEREXIT ON — 设置USEREXIT参数
设置完后的参数配置相关显示如下:
Log retain for recovery status = RECOVERY
User exit for logging status = YES

重启数据库并进行全库备份:
db2 stop force
db2 start
db2 backup db <database>

指定归档路径:(OVERFLOWLOGPATH参数)
db2 connect to <database> user <username> using <password>
db2 update db cfg using overflowlogpath "<path>"

GoldenGate中执行add trandata补全日志:
GGSCI> dblogin sourcedb sample userid db2admin,password db2admin
— 除oracle外的数据库都需要指定sourcedb参数,指定数据库名称
GGSCI>add trandata db2admin.<tablename>

其他的同步配置与Oracle中一样,需要注意的是进程配置文件中登陆DB2的部分都需要指定sourcedb这个参数(ORACLE不需要,指定了反而报错)。还有就是复制进程的配置文件中一般不能指定assumetargetdefs参数,因为不是结构一致的数据库,需要通过defgen工具生成数据定义文件进行映射。

4.3 oracle与sybase同步

Sybase数据库设置
使用sybase的SQL Advantage,用sa用户登录,执行dbcc settrunc( 'ltm', valid )修改参数。

GoldenGate中连接Sybase
GGSCI> dblogin sourcedb zhoubase userid sa password sasasa
同样做如下设置
GGSCI>add trandata <user>.<tablename>

其他配置和Oracle中一样。

需要注意的是,Sybase是个区分大小写的数据库(sql server同样)。而Oracle不区分大小写,这就导致了表和字段在复制进程映射的时候,容易因大小写问题导致映射失败。解决方法是在表名外加上双引号或者单引号,参照如下复制进程的配置文件内容:
/*
replicat repsy
sourcedefs d:\tools\GG\gg10g\dirdef\extsy.ref
USERID ddw, PASSWORD ddw
reperror default, discard
discardfile D:\repsy.dsc,append,megabytes 100
MAP “dbo.BBTEST”, TARGET “DDW.AASYBASE”; — 引号区分大小写
*/

5、GoldenGate同步方案
GoldenGate工具虽小,但它提供表级字段级同步映射,而且同步性能优异、资源消耗低,使它的灵活性很强,可以提供多种数据同步、冗灾的解决方案。

5.1 使用GoldenGate初始化加载
这里所指的GoldenGate初始化加载,只是它指提供的direct load方式,因为其他几种官方介绍的初始化方式要么需要借助其他数据库工具(如extract->SQL*Loader),要么中间走了完全没必要的步骤导致性能很差(如extract->file->replicat方式),都不算纯正的GoldenGate方式。
初始化加载架构:

上图中,显示了初始化加载启用了两条同步路线:上面一条是真正的initial load,负责将源数据端的数据一次性发送到目标数据库;下面一条,其实就是普通的GoldenGate同步进程,负责抓取初始化加载时源端数据库进行的在线数据变化。因为在实际应用中,往往需要在生产库(源数据库)不停机的状态下,将数据加载到备用数据库(目标数据库)中并应用实时同步,在数据初始化的过程中,生产库将继续进行正常的事务操作,所以此时需要有抓取进程在初始化时开始将这些变化捕获,以免数据丢失。
实际部署时需要注意正确的执行顺序,大致可以分为以下几步:
(1) 源端和目标端创建配置各个同步进程。
(2) 开启源端同步抓取进程(图上的Change Extract),开始捕获变化。
(3) 开启初始化进程(图上的Initial-Load Extract),开始数据初始化加载。
(4) 等初始化加载结束,开启目标端复制应用进程(图上的Change Replicat),开始实时同步应用。
在目标端复制应用进程(图上的Change Replicat)中,需要在参数文件中配置HANDLECOLLISIONS参数,以避免重复应用第2和第3步之间的数据变化,因为这部分数据已经包含在初始化加载中传到目标数据库中了。
在这里需要特别提醒的一个概念上的问题,GoldenGate的初始化同步不会也不需要去初始化目标端的SCN号。这个问题在我与多位数据库DBA的交流中发现,他们往往以为GoldenGate是通过SCN来判断数据的应用情况的。GoldenGate的同步与Streams不同,它不需要依赖两端数据库保持一致的SCN来应用同步,实际上它只在抓取时可能会与数据库的SCN有关联(抓取时可以指定源数据库的特定SCN号开始解析日志),在trail传输以及目标端应用时,都和源端数据库的SCN毫无关系。它的实质是通过自己的一套队列文件检查点机制来实现队列数据的管理,在目标端则通过数据的唯一键来定位数据行,trail文件最终解析成SQL语句在目标端数据库执行而实现数据的应用。所以这里的初始化加载,完全可以使用其他数据库工具来实现,比如说exp/imp、SQL*Loader、RMAN复制数据库等。
以下为一个简单的初始化加载的例子,对于实时同步配置同上面介绍的是一样的,这里不再说明,只列出初始化加载部分的进程配置。

5.1.1 GoldenGate初始化加载示例(direct load方式)
源端
添加提取进程:
GGSCI> add extract ext1,sourceistable — 没有tranlog,意味着不是通过日志方式;没有begin XXX,表示还未启动;使用sourceistable参数不会使用检查点机制
配置文件如下:
/*
extract ext1
userid ddw,password ddw
rmthost 192.168.0.44, mgrport 7401
rmttask replicat, group rept1 — 注意是rmttask,指定目标复制进程名
table ddw.test;
*/
不需要为该进程添加远端队列(rmttrail)。

目标端
添加复制应用进程:
add replicat rept1,specialrun — 表示一次性加载

/*
replicat rept1
assumetargetdefs
userid ddw,password ddw
reperror default, discard
discardfile D:\reptmy.dsc,append,megabytes 100
INSERTAPPEND — 使用直接路径加载,提高加载速度
HANDLECOLLISIONS — 当目标端已有数据时,略过重复数据错误
MAP ddw.test, TARGET ddw.test1;
*/

注意,这里的extract和replicat进程添加完后在info all中看不到这个进程,但是view report可以跟踪到。

要开始加载,在源端执行:
GGSCI> start exttmy
目标端的replicat进程不需要去启动,会自动进行数据应用。

5.1.2 与Oracle数据泵数据加载速度的比较
按照5.6.1示例中的配置,对一张600万行数据的测试表进行初始化加载,完全加载结束大约需要50分钟。
使用Oracle 10g的数据泵工具对同样的表,通过DB Link的方式进行初始化加载:
C:\>impdp ddw/ddw@orcl job_name=zhouimp tables=test CONTENT=DATA_ONLY network_link="DB148.REGRESS.RDBMS.DEV.US.ORACLE.COM"
只需要1分半钟就导完了600万行数据。两者的执行效率差别太大了。
所以在一般情况下,尽量使用其他高效的数据库传输工具来完成初始化加载,而不要用GoldenGate提高的初始化功能。

5.2 一对多数据同步(广播复制)
一对多数据同步实现架构:

GoldenGate对于多对一的实现方式,就是对于同一个源建立多个提取进程同步进行,也就是说,对应不同的目标端,分别配置同步进程进行同步。配置过程与前面是一样的。
这里的多个目标端,有可能对应不同的数据库,也有可能是同一个库中的不同对象。如果是同步到同一个库中的不同对象,除了分别配置同步进程以外,有时候也可以在一个进程中完成,比如,可以在复制端如此配置:
/*
REPLICAT rep146e1
USERID coss3,PASSWORD coss3
assumetargetdefs
REPERROR default,discard
DISCARDFILE d:\ggoracle\log\rep146e1.dsc,append,megabytes 200
HANDLECOLLISIONS
MAP ddw.test, TARGET ddw.test1;
MAP ddw.test, TARGET ddw.test2; — 同一张表同时对应多个表
MAP ddw.test, TARGET ddw.test3;
*/
当然,如果同步数据负载较大的情况下,还是建议在进程级别分开。
5.3 多对一数据同步(集中复制)
多对一数据同步架构:

多对一数据同步实现方式同一对多,也是将extract-replicat将进程拆分成多个。
多对一同步需要注意的是,所有源端和目标端的表都应该使用一致的主键约束,而且在不同的源端不应该对同一键值的数据进行维护。也就是说,需要在业务上将不同源的数据隔离开来,以防止对同一数据的覆盖更改等问题。一般用于维护业务的区域性数据、然后统一同步到业务中心数据源的业务场景。
还有一个需要注意的方面是TRUCATE的捕获,在多对一的配置下应避免捕获。因为GoldenGate处理TRUNCATE同步是直接传输了这个语句,并不会提供具体删除的数据信息(没有REDO也无法提供),所以无论哪个源端执行了TRUNCATE,如果同步到了目标端,都会直接把目标端的表数据直接删光,无论目标数据是否是来源于这个源,造成数据的不一致。

5.4 数据转换和过滤
GlodenGate中支持字段映射、数据筛选转换,以及调用执行数据库脚本或者SQL语句等,在一定条件下,甚至可以实现实时ETL的功能。

5.4.1 字段映射
GoldenGate中字段的映射一般配置在复制应用端的MAP参数中,字段映射要求两边尽量一致的字段的类型,当然也允许CHAR<->VARCHAR之类的转换。对于不同字段类型的映射,最好详细参考GoldenGate官方文档以得到足够的支持信息,并做好测试验证以防止数据丢失等。以下是字段映射的配置例子:
例子1:
/*
MAP ddw.a1test, target ddw.a2test, — target前一定要留个空格,否则会报错
COLMAP (id = id, type1 = type1, sell_date1 = sell_date2); — 字段映射配置
*/

例子2:
/*
MAP ddw.a1test, target ddw.a2test,
COLMAP (USEDEFAULTS, sell_date1 = sell_date2); — USEDEFAULTS表示自动映射同名字段
MAP ddw.a3test, target ddw.a4test; — 不同的表映射,不同的map
MAP “ddw.a5test”, target “ddw.a6test”; — 在有些大小写敏感的数据源需要引号区分大小写
*/

例子3:
/*
MAP ddw.a1test, target ddw.a2test,
COLMAP (USEDEFAULTS, num = 111, name = "abc", now_date = @DATENOW());
— 字段指定固定值,注意字符值加引号,数字值不可加引号;@DATENOW()表示当前系统时间
*/

例子4:
/*
MAP ddw.a1test, target ddw.a2test,
COLMAP (USEDEFAULTS,
transaction_date = @DATE (“YYYY-MM-DD”, “YY”, YEAR, “MM”, MONTH, “DD”, DAY),);
— 多个字符字段整合转换为目标端的一个时间字段
*/

在这里顺便插入一个很容易出错的表映射例子:
/*
map ddw.a*, target ddw.*; — 通配符表示所有a开头的表进行映射,注意的是target后面的表名千万不能也写成ddw.a*,不然会被映射成目标端aa开头的表
*/

5.4.2 字段和数据筛选
GoldenGate中字段的筛选一般都在TABLE参数中配置(目标端是在MAP参数)。一般推荐在源端extract进程配置文件中配置,这样可以有效得减小trail文件的大小,减小网络负载。以下是一些筛选配置例子(只列出配置文件的TABLE参数部分)。

(1)字段筛选:
/*
table ddw.aatest,
FETCHCOLS (id, name, type1, sell_date, value1); — 表明只提取这些字段
*/

使用指定字段做主键:
/*
table ddw.aatest,
KEYCOLS (client_taq, id);
*/

(2)数据过滤:
使用WHERE条件:
/*
table ddw.aatest, where (type1 = "1" AND type2 = "2"); — 表明只提取表中type1=’1并type2=’2’的记录
*/

如下提取非NULL值:
/*
table ddw.aatest, where (value <> @NULL);
*/

使用FILTER参数:
/*
table ddw.aatest, FILTER((num1*num2)>1000);
*/

与WHERE条件不同的是,FILTER只能后面数字,字符型需要转换后才可以使用,如:
/*
table ddw.aatest, FILTER (@STRFIND(NAME, "JOE") > 0).
*/

FILTER参数的优势是还可以指定只在某种DML操作下才过滤,比如:
/*
table ddw.aatest, FILTER((ON UPDATE, ON DELETE, (num1*num2)>1000);
— 只在UPDATE和DELETE操作时过滤num1*num2不大于1000的值
*/

5.4.3 调用执行SQL或存储过程
在GlodenGate指令库中有个SQLEXEC指令,可以用来调用执行数据库存储过程或者自定义的SQL语句,可以指定输入参数,输出参数可以作为字段与目标表映射。使用这个指令,可以实现将源表做简单连接(table join)然后将连接后结果同步到目标表,达到简单的转换目的。

在复制端配置如下(以SQL为例,procedure是一样的,改成过程名即可):
/*
replicat repjoin
userid ddw,password ddw
sourcedefs d:\tools\GG\gg10g\dirdef\extjo.ref
reperror default,discard
discardfile D:\repjoin.dsc,append,megabytes 100
gettruncates
map ddw.a1test, target ddw.a12test,
sqlexec (id testid, — 自定义执行语句的唯一标识
query "select name,value1 from a2test where name_id=:id_param", — :id_param为输入参数
params (id_param = NAME_ID)), — 将输入参数指定为源表中某列
如果没有输入参数,则这部分改为NOPARAMS
colmap (USEDEFAULTS, name = testid.name, value1 = testid.value1);
— 新的字段映射,testid.name表示语句输出参数name
*/

上面的配置案例,实现了将ddw.a1test表中name_id字段通过字典表a2test转换为对应的真实name值,并增加了一个value字段,然后映射到ddw.a12test表中。ddw.a12test表中的记录实际就是前面ddw.a1test表和a2test表连接生成的记录。

但是,这里存在一个问题:字典表a2test是在源数据库呢,还是在目标数据库?显而易见,配置在复制进程的配置文件中,那条语句是在目标端数据库执行的(如果执行procedure那么这个过程也必须建立在目标端),字典表a2test在目标端(在我这个例子中)。而且同步是由表ddw.a1test上的事务触发的,字典表a2test中的数据无论怎么改都不会引起这个数据同步。这种情况下,可以考虑将字典表a2test也进行同步,来解决这个问题。
SQLEXEC指令也可以在提取进程中使用。如果有输出参数作为额外的映射列,这个时候需要将查询结果也一并传输过去。可以通过参数TOKENS进行传递,然后再在目标端映射。
以下对TOKENS的使用进行说明。

使用USER TOKENS AREA
可以使用TOKENS参数,在提取端将自定义的数据放入trail中,传递到目标端,映射到目标端的表中。这里针对前面SQLEXEC提出的问题示例。

提取端extract的TABLE配置:
/*
TABLE ddw.test,
sqlexec (id sqlid,
query "select node_id codeid from ic_sysnode where rownum=1", NOPARAMS),
TOKENS (TK_CODE = sqlid.codeid); — 将提取端查询出的node_id字段值,标识为TK_CODE放入ddw.test表的trail文件中,一起传递
*/

目标端replicat的MAP配置:
/*
MAP ddw.test, TARGET ddw.testother,
COLMAP (USEDEFAULTS,SITE_CODE = @TOKEN("TK_CODE")); — 将TK_CODE值映射给目标字段
*/

5.4.4 数据库DML操作过滤
数据库DML操作过滤,这里是指选择是否捕获INSERT、UPDATE、DELETE。在某些业务场景下,只需要捕获某一种特定的DML操作即可,比如业务数据库往数据仓库的数据同步,往往只需要捕获INSERT操作,而对于UPDATE、DELETE则不允许同步目标库。
默认下,INSERT、UPDATE、DELETE都是捕获的,可以分别在Extract进程的配置文件中加入IGNOREINSERTS、IGNOREUPDATES、IGNOREDELETES进行忽略。当然,在这种情况下,业务上需要做相应的限制。比如忽略DELETE操作时,源数据库应禁止重复插入DELETE掉的键值。
参数使用示例(表示只捕获INSERT):
/*
IGNOREUPDATES
IGNOREDELETES
*
/
TRUNCATE是一种特殊的删除操作,默认配置下GoldenGate不进行捕获,一般需要在Extract进程的配置文件中加入GETTRUNCATES来指定捕获。

5.5 关于目标端高数据安全性下的GoldenGate配置方案
5.5.1 配置方案
因为GoldenGate的标准配置下,是通过源端抓取进程向目标端发送队列文件的方式传输数据的,但在实际应用中,会出现这么一个关于安全方面的问题:如果上级机器的安全策略不允许外网直接往里发送数据,如何进行数据同步配置?
GoldenGate是有提供一个由目标端主动“申请”源端进行数据传输的方式,以保证内外网不同安全域下的数据安全保障。
解决方案的体系架构如下:

主要是通过目标端一个额外的alias Extract进程,实现由目标端(可信任域)主动请求、向源端(未信任域)提供数据传输的连接的过程。

具体的驱动模式如下(翻译自官方文档,可能表述得不准确):
(1) 启动可信任域的alias Extract进程
(2) 可信任域的GGSCI向未信任域mgr主进程发送消息,以启动相应的passive Extract进程。消息包含可信任域的主机名或IP,以及一个可信任域mgr主进程的端口号。
(3) 未信任域接受消息后,启动passive Extract进程,并打开一个可用的端口号。
(4) 未信任域mgr主进程将该端口号返回给可信任域的GGSCI。
(5) 可信任域的GGSCI向本地mgr主进程发送请求以启动Collector进程。
(6) 本地mgr启动Collector进程,通过未信任域提供的端口号对未信任域进行监听。
(7) Collector进程打开与未信任域passive Extract进程的连接。
(8) 同步数据通过连接从未信任域passive Extract进程传输到Collector进程,然后写入本地trail,被Replicat进程应用。

这里未信任域的passive Extract进程,即是源端的data pump Extract进程,所以只需要改动源端的data pump Extract进程、新增一个alias Extract进程即可(Collector进程由目标端mgr自动配置)。

5.5.2 配置案例
1.源端配置(146上)
(1)创建提取进程(与普通情况下完全一样)
GGSCI> add extract exta,tranlog,begin now
配置文件exta.prm:
/*
extract exta
SETENV (ORACLE_SID = ORCL)
userid COSS360,password COSS360
exttrail C:\ggoracle\dirdat\ea
dynamicresolution
gettruncates
TABLE COSS360.per_test, keycols (sampletime, objectid);
*/
创建本地队列:
GGSCI> ADD EXTTRAIL C:\ggoracle\dirdat\ea,extract exta

(2)pump进程(passive extract进程)
创建passive pump:
GGSCI> ADD EXTRACT pumpa, exttrailsource C:\ggoracle\dirdat\ea, begin now, passive, desc "passive pump" — passive表示为passive extract process
配置文件pumpa.prm:
/*
extract pumpa
userid COSS360,password COSS360
— rmthost 192.168.0.142, mgrport 7801 — 原先的rmthost需要被注释
RMTHOSTOPTIONS compress — passive extract专有参数
rmttrail D:\ggoracle\dirdat\trail146\ea
NOPASSTHRU
gettruncates
TABLE COSS360.per_test, keycols (sampletime, objectid);
*/
创建远端队列:
add rmttrail D:\ggoracle\dirdat\trail146\ea extract pumpa

2.目标端配置(142上)
(1)添加aliad extract进程
alias Extract进程不需要配置文件
添加语法:
ADD EXTRACT <group>
, RMTHOST {<host name> | <IP address>}
, {MGRPORT <port>} | {PORT <port}
[, RMTNAME <name>]
[, DESC “<description>”]
此处测试的创建命令如下:
GGSCI> add extract ext146pa, rmthost 192.168.0.146, mgrport 7801, rmtname pumpa
— 需要定义源端的地址、端口,而且如果alias extract名称和passive extract名称不同,需要特别指定rmtname

(2)添加应用进程(与普通情况下完全一样)
GGSCI> add replicat rep146ea exttrail D:\ggoracle\dirdat\trail146\ea,nodbcheckpoint
配置文件rep146ea.prm:
/*
REPLICAT rep146ea
USERID coss3,PASSWORD coss3
assumetargetdefs
REPERROR default,discard
DISCARDFILE d:\ggoracle\log\rep146ea.dsc,append,megabytes 200
gettruncates
HANDLECOLLISIONS
BATCHSQL BATCHESPERQUEUE 200, OPSPERBATCH 2000
MAP coss360.per_test, TARGET coss3.per_test,
keycols (sampletime, objectid);
*/

3.同步进程的启动和关闭
注意,passive extract(这里是pumpa)不应该被手动启动(手动也无法启动)。在上面的进程创建和配置完成后,正确的启动方式如下:
(1)源端start exta,目标端start rep146ea
(2)目标端start ext146pa(alias Extract)
(3)在正确的配置下,pumpa会自动启动。Pumpa启动后,同步正常开始。
同样,进程关闭时,无论在源端关闭passive extract或是在目标端关闭alias extract,对应的alias extract和passive extract都会自动关闭。

5.6 GoldenGate双向复制(active-active)
双向复制系统架构如下:

GoldenGate双向复制,意即两端数据库互为源数据,无论在哪一端上对业务数据进行操作,都将同步应用到另一端。

5.6.1 双向复制的注意点
1.防止数据循环
双向复制中,最主要的问题是需要防止数据的循环应用。在GoldenGate中,需要从两方面进行预防:
(1)防止Extract进程抓取Replicat进程的SQL操作。
在默认配置下,GoldenGate的Extract进程会忽略捕获由Replicat执行的SQL操作(Teradata除外,需要进行额外配置),所以这部分一般不需要额外设置。
(2)使Extract进程识别本地Replicat执行的DML事务,并进行忽略。
这步在Oracle(10g and later)中的配置为在Extract进程加入参数:
TRANLOGOPTIONS EXCLUDEUSER <user name> 进行排除。
不同的数据库这里需要配置的参数不同。如果是Oracle 9i或之前的版本,需要配置tracetable。

2.防止数据冲突
由于是双向复制,那么当两端都对同一数据进行操作时,就会发生冲突。比如同时对某行数据进行修改,修改的操作将会被覆盖(视LAG以及事务的先后);又比如两端插入或删除相同键值的数据。
对于这类数据冲突,最好是在业务应用层解决。比如,可以划分两端数据库应用的业务范围,一部分数据只在一端修改维护,另一端则修改维护其他数据;在两端定义不同的键值生成策略;关注同步表上的触发器和on delete cascade约束。也可以借助GoldenGate的映射和过滤功能,对于两端同步的数据进行区分。
总之,在配置双向复制环境时,需要综合考虑当时业务情况,一般都需要在应用层进行适当的修改,以防止数据冲突带来的数据丢失和不一致。

5.6.2 双向配置示例
这个示例中,ggdba用户作为GoldenGate专用用户,ddw和ddws分别为两端数据库需要同步的schema(也可以同名,这里是为了便于区别),通过在两端Extract中配置排除ggdba的操作防止循环应用。以下ddw结尾的进程均在ddw用户所在数据库,ddws结尾的进程均在ddws用户所在数据库。

(1) ddw==>ddws

添加提取进程:
GGSCI> add extract extddw,tranlog,begin now
/*
extract extddw
userid ggdba,password ggdba
exttrail E:\ggoracle\dirdat\e1
tranlogoptions excludeuser ggdba — 排除捕获ggdba
dynamicresolution
gettruncates
TABLE ddw.*;
*/
GGSCI> add exttrail E:\ggoracle\dirdat\e1, extract extddw

添加datapump:
GGSCI> add extract pumpddw,exttrailsource E:\ggoracle\dirdat\e1,begin now
/*
extract pumpddw
userid ggdba,password ggdba
rmthost 192.168.1.101, mgrport 7801
rmttrail E:\ggoracle\dirdat\rep\e1
PASSTHRU
gettruncates
table ddw.*;
*/
GGSCI> add rmttrail E:\ggoracle\dirdat\rep\e1, extract pumpddw

添加复制应用进程
GGSCI> add replicat repddws,exttrail E:\ggoracle\dirdat\rep\e1, nodbcheckpoint
/*
replicat repddws
userid ggdba,password ggdba
ASSUMETARGETDEFS
reperror default,discard
discardfile E:\ggoracle\log\repddws.dsc,append,megabytes 200
gettruncates
HANDLECOLLISIONS
MAP ddw.*, TARGET ddws.*;
*/

(2) ddws==>ddw

添加提取进程:
GGSCI> add extract extddws,tranlog,begin now
/*
extract extddws
userid ggdba,password ggdba
exttrail E:\ggoracle\dirdat\e2
tranlogoptions excludeuser ggdba — 排除捕获ggdba
dynamicresolution
gettruncates
TABLE ddws.*;
*/
GGSCI> add exttrail E:\ggoracle\dirdat\e2, extract extddws

添加datapump:
GGSCI> add extract pumpddws,exttrailsource E:\ggoracle\dirdat\e2,begin now
/*
extract pumpddws
userid ggdba,password ggdba
rmthost 192.168.1.101, mgrport 7801
rmttrail E:\ggoracle\dirdat\rep\e2
PASSTHRU
gettruncates
table ddws.*;
*/
GGSCI> add rmttrail E:\ggoracle\dirdat\rep\e2, extract pumpddws

添加复制应用进程:
GGSCI> add replicat repddw,exttrail E:\ggoracle\dirdat\rep\e2, nodbcheckpoint
/*
replicat repddw
userid ggdba,password ggdba
ASSUMETARGETDEFS
reperror default,discard
discardfile E:\ggoracle\log\repddw.dsc,append,megabytes 200
gettruncates
HANDLECOLLISIONS
MAP ddws.*, TARGET ddw.*;
*/

开启所有进程,双向复制开始。

6、GoldenGate数据同步性能测试
这个GoldenGate同步性能测试,是在以前项目中,为测试该工具是否能满足实际项目中数据同步的实时性、高负载性,自己做的一次伪性能测试。
由于测试条件和个人能力所限,测试仅在局域网内的普通PC(实际为虚拟机上划分的两个OS环境)上进行;测试中的事务仅为单一简单语句(Insert),同步的表为一对一进行同步;测试中源端只提供了每秒5000多条的事务量,实际可以调整得更高些(当然受数据库性能制约),但在这个条件下峰值测试没有什么意义;GoldenGate的参数配置也不能满足最优化配置。
测试主要目的:
(1) 反映在这个条件下,实时同步大致的性能效率。
(2) 提出一个GoldenGate实时同步性能测试的方案。
(3) 提出实际项目部署中,需要考虑到哪些负载问题。

6.1 测试中主要监测数据和监测方式
(1)源端和目标端每秒提交数据量
测试数据生成时,以1秒为间隔统计2端端口性能表的数据量,记录在测试日志表GG_PERFORMANCE_TESTLOG中。

(2)测试过程中两端数据库生成的REDO量
测试前清空两端数据库的归档日志,测试后switch日志组,统计归档文件生成量。同时在测试中在线监测相关会话生成的REDO量。

(3)生成的测试数据在表空间中占用的空间大小
测试后分析per_test表进行空间大小统计。

(4)测试数据传输时生成的trail文件大小
关闭trail文件自动清除,比较测试前后相应trail队列的增长情况。

(5)记录测试时两端的网络流量情况
通过金山卫士的流量监控功能监控。同时在线监测replicat端的lag情况。

6.2 测试脚本和GoldenGate配置
同步性能测试在2个虚拟机之间进行,IP分别为192.168.0.146和192.168.0.142,由146向142同步数据,146上insert一条新记录作为一个事务提交。同步测试表为PER_TEST。

6.2.1 测试脚本

(1)DB Link
为监控方便,146上建立142的DB Link,主要为统计两边数据库提交的数据量,并不用于数据同步:
create database link DB142.REGRESS.RDBMS.DEV.US.ORACLE.COM
connect to coss3 identified by coss3
using 'orcl142'; — 146上142数据库的服务名

(2)性能测试日志表
create table GG_PERFORMANCE_TESTLOG
(
RECORD_DATE TIMESTAMP(6),
COUNTS_142 NUMBER,
COUNTS_146 NUMBER,
DIFFERENCE NUMBER,
MARKS VARCHAR2(500)
)

(3)测试数据生成脚本
CREATE OR REPLACE PROCEDURE P_GG_PERFORDATA(
/*
* INSERT TEST DATA FOR TESTING GOLDENGATE SYNC PERFORMANCE DATA;
* THE USER WHO EXEC PROCEDURE P_GG_PERFORDATA NEEDS 'execute on dbms_lock' PRIVILEGE
* AUTHOR ZHOUJIONG 2011-04-07
*/
p_looptime in pls_integer
)
AS
v_date date;
Begin
v_date:=sysdate;
for i in 1..p_looptime loop
/** port performance data **/
insert into PER_TEST
(sampletime,
objectid,
step,
OBTAINABLE,
PORT_IN_PKT_BROAD_SPEED,
PORT_IN_PKT_DIS_SPEED,
PORT_IN_PKT_ERR_SPEED,
PORT_IN_PKT_MULTI_SPEED,
PORT_IN_PKT_NUNI_SPEED,
PORT_IN_PKT_UNI_SPEED,
PORT_IN_SPEED,
PORT_OUT_PKT_BROAD_SPEED,
PORT_OUT_PKT_DIS_SPEED,
PORT_OUT_PKT_ERR_SPEED,
PORT_OUT_PKT_MULTI_SPEED,
PORT_OUT_PKT_NUNI_SPEED,
PORT_OUT_PKT_UNI_SPEED,
PORT_OUT_SPEED)
values
(v_date,
i,
i,
'T',
32,
32,
32,
32,
32,
32,
32,
32,
32,
32,
32,
32,
32,
32);
commit;
end loop;
dbms_lock.sleep(600); — 执行完毕后停顿10分钟,便于在线收集redo量
Exception
when others then
dbms_output.put_line(substr(SQLERRM, 1, 1000));
End P_GG_PERFORDATA;

(4)数据统计脚本
每秒统计142、146上端口性能表中已提交的数据量和差值。
CREATE OR REPLACE PROCEDURE P_GG_TESTLOG(
/*
* COMPARE THE ROWS COUNTS BETWEEN 146 AND 142 FOR TESTING GOLDENGATE SYNC;
* IT SHOULD BE CALLED BEFORE WHEN THE P_GG_PERFORDATA WILL BE CALLED
* AUTHOR ZHOUJIONG 2011-04-07
*/
p_marks in varchar2 default null — for marking which tests the records belong to
)
AS
v_timestamp timestamp;
v_rows_146 number:=0;
v_rows_142 number:=0;
begin
for i in 1..1200 loop
v_timestamp:=systimestamp;
select (select count(*) from per_test) num1,
(select count(*) from MOC.ELCARO.SU.VED.SMBDR.SSERGER.241BD|tset_rep#MOC.ELCARO.SU.VED.SMBDR.SSERGER.241BD|tset_rep) num2
into v_rows_146,v_rows_142
from dual;

insert into GG_PERFORMANCE_TESTLOG(RECORD_DATE,COUNTS_142,COUNTS_146,DIFFERENCE,MARKS)
values (v_timestamp,
v_rows_142,
v_rows_146,
v_rows_146-v_rows_142,
p_marks);
commit;
dbms_lock.sleep(1);
end loop;

Exception
when others then
dbms_output.put_line(substr(SQLERRM, 1, 1000));
end P_GG_TESTLOG;

6.2.2 GoldenGate配置
为统计生成的trail文件量,首先将两端的mgr.rpm中的PURGEOLDEXTRACTS C参数注释掉,并重启mgr进程。

(1)146上extract进程配置
ext3.prm
/*
extract ext3
SETENV (ORACLE_SID = ORCL)
userid COSS360,password COSS360
exttrail C:\ggoracle\dirdat\e3
dynamicresolution
gettruncates
TABLE COSS360.per_test, keycols (sampletime, objectid);
*/

pump3.prm
/*
extract pump3
userid COSS360,password COSS360
rmthost 192.168.0.142, mgrport 7801
rmttrail D:\ggoracle\dirdat\trail146\e3
NOPASSTHRU
gettruncates
table COSS360.res_p_s_*;
*/

(2)142上应用进程配置
rep146e3.prm
/*
REPLICAT rep146e3
USERID coss3,PASSWORD coss3
— SOURCEDEFS d:\ggoracle\dirdef\ext146\ext3.ref
assumetargetdefs
REPERROR default,discard
DISCARDFILE d:\ggoracle\log\rep148e3.dsc,append,megabytes 200
gettruncates
HANDLECOLLISIONS
BATCHSQL BATCHESPERQUEUE 200, OPSPERBATCH 2000
MAP coss360.per_test, TARGET coss3.per_test,
keycols (sampletime, objectid);
*/

6.3 测试步骤
(1)清空两端测试表
SQL> truncate table per_test;

(2)清空归档和日志
sqlplus sys/broada_plat@orcl142 as sysdba
SQL> alter system switch logfile;
SQL> host RMAN target sys/broada_plat@orcl142
RMAN> delete noprompt archivelog all;
RMAN> exit
SQL> conn sys/broada_plat@orcl146 as sysdba
SQL> alter system switch logfile;
SQL> host RMAN target sys/broada_plat@orcl146
RMAN> delete archivelog all;
这里需要注意的是,extract进程应该在归档清空后开始抓取,即建立extract进程应该在这个时间点之后begin。主要了防止日志大小统计的不准确。

(3)开启两端GoldenGate进程,记录初始trail file大小
146:2K
142:2K

(4)执行测试脚本
分别在两个命令行窗口中执行2个脚本,其中p_gg_testlog提前于P_GG_PERFORDATA执行,以记录完整的测试信息:
SQL> exec p_gg_testlog(p_marks => 'one')
SQL> exec P_GG_PERFORDATA(p_looptime => 10000000); — 实际执行时间约1882秒

(5)测试数据生成结束、会话未关闭时(即10分钟停顿时间内)数据监控
查看相应SESSION
146 user commit: 10000000次
142 user commit: 10082次
备注:在应用端配置了每1000条事务进行一次批量提交

会话REDO生成情况统计:
select s.sid, n.name, round(s.value / 1024 / 1024) "Size Mb"
from v$sesstat s, v$statname n
where s.statistic# = n.STATISTIC#
and n.name like '%redo size%'
order by 3 desc;
统计结果:
142上会话redo量(SID 288)


1 288 redo size 1679M

146上会话redo量(SID 211)


1 211 redo size 10037M

金山卫士流量监控中记录142总下载流量为3.1G。

GoldenGate应用端控制台中,查看lag信息,基本在3秒以内。

(6)统计表大小
SQL> analyze table per_test compute statistics; — 190s左右
SQL> select s.segment_name,(s.bytes/1024)||'K' bytes from user_segments s where s.segment_name=UPPER('per_test');
146上


1 PER_TEST 770048K

142上


1 PER_TEST 770048K

两端的rows均为1000万行,传输中无数据丢失。

(7)检查trail文件大小
测试后trail文件大小:(e3*)
146:3,326,940,923
142:3,326,956,814

(8)检查生成的归档文件大小
sqlplus sys/broada_plat@orcl142 as sysdba
SQL> alter system switch logfile;
sqlplus sys/broada_plat@orcl146 as sysdba
SQL> alter system switch logfile;
146:12,413,898,752
142:1,826,665,472
备注:146上的归档还包含一部分因日志表数据插入造成的归档数据。但在前面redo统计中则不包含,因为2个脚本分别运行,在不同的会话下。

(9)查看146上日志表
通过以下语句查看这次测试的日志表数据:
select * from gg_performance_testlog t where regexp_like(marks,'one') order by 1
日志表记录了同步过程中,两端同步表已提交数据的数量和差值,每秒记录一次。可以通过日志表的数据,计算出每秒事务量,并估算出同步效率。如果差值大,表明网络延迟较大;如果差值不断增大,表明应用端同步效率较低,无法满足源端的事务量。
另一文档《性能测试日志表数据》中记录了这次测试的日志表数据。

6.4 性能测试结果
6.4.1 测试数据计算
测试日志表中,记录了测试数据生成时间是从9:58:34到10:31:06,约32分32秒,生成1000万条测试记录,每生成一条记录提交一次,所以:
每秒事务量=10,000,000/1952=5123 次/秒

根据测试日志表记录,统计差值情况:
select avg(difference) avg,max(difference) max from gg_performance_testlog t
where regexp_like(marks,'one') and difference>0;
avg max


17895.8988970588 51260
即同步时两端记录平均差值约17896行,最大差值为51260行。差值并不随着时间增大,表明应用进程的应用效率能满足抓取的每秒事务量。

146端在10:31:06完成所有事务,相应的,142端10:31:11完成所有应用,最终同步lag约5秒。

生成的trail文件大小3,326,956,814字节,约3172.8M或3.1G,与前面记录的网络传输流量3.1G基本一致,所以:
每秒网络传输流量=3172.8/1952=1.6M/s

源端1000万条记录,相应生成的redo为10037M,约9.80G;应用端同步生成的redo为1679M,约1.64G。记录在表中的存储大小,两端均为752M。所以:
源端每秒日志量=10037/1952=5.1M/s
应用端每秒日志量=1679/1952=0.86M/s
每秒trail文件大小=3172.8/1952=1.6M/s
GoldenGate传输压缩比=9.8:3.1=3.16:1
两端数据库日志比=10037: 1679=5.98:1

比较如下:

源端 目标端
总时间 1952s
事务完成时间 10:31:06 10:31:11
数据量 1000万行
每秒事务量 5123次/s
数据存储大小 752M
产生的REDO 10037M 1679M
每秒日志量 5.1M/s 1.6M/s
TRAIL文件大小 3172.8M
网络流量 1.6M/s

6.4.2 测试结果
从上述测试数据中可得出:
(1) 源端每秒5123次事务,生成5.1M的日志;
(2) GoldenGate抽取压缩后每秒形成1.6M/s的trail文件,并通过网路传输到应用端;
(3) 应用端应用每秒产生0.86M的日志,应用延迟约5秒。

从这次测试中,可以看出,实时同步,每秒5000次的事务量,在普通PC上的数据库即可满足应用端实时应用同步数据。同时每秒5000次的事务量会产生1.6M/s的网络流量负载,由于测试是在局域网内进行,在实际项目的实时同步中,要保证同步的实时性,就需要考虑到网络传输的能力,相对来说这一方面的压力可能会更大。GoldenGate可以再压缩传输的trail,同时可以借助BATCHSQL参数批量应用,缩减了应用端的数据库压力和生成的日志大小。

7、GoldenGate推荐配置
这里的推荐配置并不一定是必须的,但往往是有益无害的,在正式项目环境中强烈推荐。很多配置都没有出现在我前面的例子中,一来是减小篇幅,简化案例的配置复杂度,二来我想放在这里集中介绍,可能效果会更好。
这部分内容将在后续继续补充完善。

7.1 添加必要的环境参数
建议在各Extract、DataPump、Replicat进程配置中加入部署环境的环境变量,以避免部署环境的复杂性带来影响。
特别是以下三个:
/*
SETENV (NLS_LANG="AMERICAN_AMERICA.ZHS16GBK")
SETENV (ORACLE_HOME = "E:\oracle\product\10.2.0\db_1")
SETENV (ORACLE_SID = JIONG)
*/

7.2 BATCHSQL参数
GoldenGate的Replicat进程,根据接收到的trail文件生成SQL语句,然后在目标端执行这些SQL。为了提高执行效率,默认下这些SQL语句是分批提交的。Replicat SQL的执行方式有三种,如下图所示:

在Relicate中配置BATCHSQL参数,则可以使Relicate进程在可能的情况下,以BATCHSQL的模式在目标端执行SQL。在BATCHSQL模式下,Relicate进程组织相似的SQL放入数组中,然后一同执行。以这种模式应用SQL能减少目标端数据库的事务数,减少写GoldenGate检查点的次数并减小相应的I/O量,因此提升目标端Relicate进程的性能。
当然,并不是所有时候都会有相似的SQL可以组织到一起的,如果无法在BATCHSQL模式下执行,GoldenGate将会尝试普通模式(图中的normal mode,默认1000个事务提交一次),不会因为这个参数引起报错。所以推荐在Relicate配置中都加入这个参数的设置。
BATCHSQL配置示例:
/*
BATCHSQL OPSPERBATCH 2000 — OPSPERBATCH表示一个BATCH最多包含多少行操作
*/
BATCHSQL可以指定子参数设置,也可以只配置一个BATCHSQL使用默认的子参数值。其他BATCHSQL子参数介绍请参看《Oracle GoldenGate Reference Guide》

7.3 数据库用户密码加密
由于GoldenGate所需的用户权限较大,而每个GoldenGate进程配置文件中都需要设置该用户和密码用于数据库登陆,出于安全性的考虑,强烈建议将密码进行加密。当然,如果已经采用了trail文件加密等其他加密级别更高的安全措施,那么这部分就没必要了。
加密方式如下:

(1)生成密钥
这步不是必须,也可以使用GoldenGate默认的密钥default,但是既然是为了安全性,推荐生成自己的密钥进行加密。
在GoldenGate安装目录下,keygen工具生成密钥:
GG_HOME> keygen 128 4 — 128指密钥长度,最大128位;4表示生成4个密钥
然后将生成的密钥复制下来,新建个文本文档,拷贝进去,内容如下:
/*
mykey1 0x0D1E636569D147474B17DE700EB76B0E
mykey2 0x1024106005B7DE2AF9765A768A49650F
mykey3 0x132ABD5AA19C750EA7D6D67B06DC5E10
mykey4 0x16306A553C820C7256365301826E5811
*/
这里的mykey1是自己定义的密钥逻辑名,用来一会调用时用,后面的一长串是刚才生成的密钥。将文本保存,注意文本名必须是ENCKEYS,大写,不带后缀。
然后将该密钥文本,放置在源端和目标端GoldenGate安装目录下。

(2)生成加密后的密码
在GGSCI接口命令行中对当前的数据库用户密码进行加密:
GGSCI> encrypt password <PASSWORD> encryptkey <key>
这里的<key>,可以是上一步定义的密钥逻辑名,如mykey1,也可以用GoldenGate自带的,即default。
命令执行后生成一串加密后的密码值,如:AACAAAAAAAAAAAFAYFVFUCAHOHDGIFWB

(3)应用加密密码
使用加密后的密码值,需要调整一下相应的参数:
/*
USERID ddw, PASSWORD <加密后的密码>, ENCRYPTKEY <key>
*/

如果是使用ASM实例的,则如下:
/*
TRANLOGOPTIONS ASMUSER SYS@<ASM_instance_name>,
ASMPASSWORD <加密后的密码>, ENCRYPTKEY <key>
*
/

想要立刻验证加密后的密码是否可用,可以用DBLOGIN命令测试:
GGSCI> dblogin userid ggdba,password <加密后的密码>, ENCRYPTKEY <key>
如果登陆数据库成功,就没问题了。

7.4 trail再压缩
当数据进行异地传输时,网络负载是影响数据传输效率的关键因素。GoldenGate的其中一个优势是,它极大地压缩了传输的trail文件,通过前面的性能测试也可以看到,日志压缩比在3:1以上。但是如果传输事务量非常大的时候,这样的压缩比有时还是无法满足一般的网络负载要求。在默认压缩(redo=>trail)的基础上,GoldenGate提供了再压缩方案:在传输trail之前对其进行进一步的压缩,然后在写入远端trail之前再进行解压。官方文档中说明这次再压缩的压缩比至少在4:1,在我实际测试中差不多达到10:1。
注意GoldenGate的再压缩过程,由于在写入远端trail前已经经过了解压,所以单纯比较两端的trail文件大小会毫无觉察(我曾经一度以为该参数无效)。实际上借助流量监控工具可以监测到,传输同样大小的trail文件,再压缩方式的实际网络流量明显要小的多。这种方式的好处是对Replicat进程提取trail毫无影响,从而也避免了加重原本负载就相对较大的Replicat进程。
GoldenGate的再压缩,是在负责向远端发送trail的Extract进程中配置的,因此一般情况下都是配置在datapump中。配置很简单,在RMTHOST参数中加入COMPRESS子参数,如下:
/*
rmthost 192.168.0.142, mgrport 7801, COMPRESS, COMPRESSTHRESHOLD 0
— COMPRESS启用再压缩,COMPRESSTHRESHOLD表示对大于该值的trail记录块进行压缩,取值0到28000,默认1000,设置为0表示全部进行压缩
*
/
启用了压缩后,势必会消耗额外的CPU,在同步事务量较大的情况下,需要考虑CPU负载。但实际上在大部分的GoldenGate应用场景中,网络负载都远远大于CPU负载,启用trail再压缩的可能性还是很大的。用或是不用,取决于具体的部署环境很业务情况。

8、GoldenGate Troubleshooting
GoldenGate的配置过程中,难免会出现各种各样的错误,要快速定位问题的原因,需要借助它提供的各类进程信息和运行日志。
在Replicat端,还可以查看对应的discardfile,以获得数据复制时数据冲突的信息,比如因主键冲突无法插入的数据行。
对于一些GoldenGate的错误信息,可以查阅《Oracle GoldenGate Troubleshooting and Tuning Guide》,当然,你不能太指望它,有很多错误号并没有列在其中。现在讨论和使用GoldenGate的已经越来越多了,很多问题可以在官方或其他论坛(如ITPUB)找到。
官方论坛地址:http://forums.oracle.com/forums/forum.jspa?forumID=860&start=0

8.1 一些常用的进程信息和日志的查看方式
(1)GGSCI> info all — 查看各进程的运行概况
也可以直接info <进程名>,这样可以看到详细的检查点信息。
(2)GGSCI> lag <进程名> — 查看进程LAG
显示最后一次数据处理的延迟。
(3)GGSCI> view report <进程名> — 查看进程运行日志
显示进程详细的运行信息,包括进程配置参数、进程恢复信息、当前的出错信息描述等等。该命令是最常用最有价值的问题查看方式。
(4)GGSCI> stats <进程名> — 查看进程运行的统计信息
显示同步的各类DML操作数量等。

8.2 解析trail文件
有时候,为了定位错误原因,或者验证传输配置是否正确,需要解析trail文件。GoldenGate提供了一个Logdump工具用来解析trail文件里的内容。
在GoldenGate安装目录下启动工具:
GG_HOME> logdump
Logdump 1 >open E:\e1000001 — 打开某个trail文件
输出:
Current LogTrail is E:\e1000001
设置输出内容:
Logdump 2 >ghdr on — 显示trail头部
Logdump 3 >detail on — 显示具体内容
Logdump 4 >usertoken on — 显示TOKEN数据内容
Logdump 5 >n — 开始显示trail内容,连续执行相当于翻页
一开始显示的是文件头部信息。连续执行n可以查看下面的内容,直到没有新的内容输出为止。该工具设置命令较多,具体可以通过help查看。
下面是一个trail文件解析后的输出:

通过解析trail文件查看传输的具体内容,曾帮我定位并解决了好几次在配置中遇到的问题。

附: GoldenGate新版本的一个特性
在整理这篇文档的时候,为了测试验证某些配置的正确性,新下载了最新版本的GoldenGate进行测试。
当像往常一样添加extract进程时有如下警告信息:
GGSCI > add extract ext1,tranlog,begin now
提示如下:
2011-05-17 10:23:41 WARNING OGG-01756 Cannot register EXTRACT EXT1 with databa
se because of the following SQL error: OCI Error ORA-06550: line 1, column 3128:

PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 1, column 3117:
PL/SQL: SQL Statement ignored (status = 0). See Extract user privileges in the O
racle GoldenGate for Oracle Installation and Setup Guide. You can manually regis
ter this group with the REGISTER EXTRACT command.
EXTRACT added.

此时按提示手工注册该进程也失败:
GGSCI > register extract ext1 logretention

2011-05-17 10:25:31 ERROR OGG-01755 Cannot register or unregister EXTRACT EX
T1 because of the following SQL error: OCI Error ORA-06550: line 1, column 3128:

PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 1, column 3117:
PL/SQL: SQL Statement ignored (status = 0). See Extract user privileges in the O
racle GoldenGate for Oracle Installation and Setup Guide.

问题解决:
根据警告提示,可以基本判定是用户权限的问题。因为操作系统登陆的是DBA权限的用户,所以换SYSDBA用户尝试:
GGSCI > dblogin userid sys,password sys SYSDBA
Successfully logged into database.
GGSCI (zhoujiongfield) 7> register extract ext1 logretention

2011-05-17 10:32:03 INFO OGG-01749 Successfully registered EXTRACT EXT1 to
start managing log retention at SCN 651955.

注册完成,这时再创建其他的进程,也没什么问题了。

问题分析:
在我以往的进程配置中,从来没有出现过这个情况,一般进程的创建根本不需要这么高的权限,没有register这一过程,一般借助OS认证就OK了,不需要dblogin一个SYSDBA权限的用户。那为什么这次需要进行注册?在以前的OGG 11.1官方文档中均无介绍。
查询最新的官方文档(2011-04-20发布的版本),才发现register相关的资料。Register Extract是开启了新版本的一个新特性:Extract通过借助RMAN来保留Extract恢复所需要的数据库归档日志,相当于开启一个日志保留策略。适用于10.2以上版本的Oracle。通过Unregister Extract关闭,对于其他功能并无影响。

深层思考:
了解GoldenGate或者同类工具的同学们都知道,通过日志捕获事务的方式虽然性能优良,但是它毕竟是依赖于数据库日志信息的,势必对数据库日志维护带来新的挑战。单独通过RMAN或者其他备份工具管理数据库备份和归档日志,很有可能发生事务日志信息还未被GoldenGate抓出就已经被清除了,导致同步失败。要避免出现这种情况,以往只能调整日志冗余策略(比如增加日志保留时间,牺牲大量的磁盘空间),或者通过编写复杂的脚本提取GoldenGate所读到的RBA来决定需要保留的归档日志。Register Extract的新特性,应该是为了解决这一难题,以方便日志管理和防止数据丢失问题。虽然目前官方文档并没有对这个特性的深入介绍,具体的使用效果还需要进一步的验证,但这个特性无疑是值得我们关注的。

参考文档
《Oracle GoldenGate Oracle Installation and Setup Guide》
《Oracle GoldenGate Administrator's Guide》
《Oracle GoldenGate Reference Guide》
《Oracle GoldenGate Troubleshooting and Tuning Guide》