
今天来介绍一下Oracle GoldenGate之数据初始化,初始化数据的先决条件:
打开源端库最小附加日志,确保同步表中没有nologging的表
禁用主库的DDL操作
确认目标端表是空的
利用map参数按表大小开启多个同步进程以提升同步效率
禁用外键和检查约束
有主键或唯一索引(或者利用keycols参数)
删除除主键之外的索引,同步完成后再添加以提高效率
如果表结构不一致需要利用表定义文件
如果源端数据处于变化状态,需要另外加一组同步进程
一 背景介绍
随着设备更新换代和数据库版本更迭,数据迁移已经成为数据库运维的日常操作之一。
数据迁移的方法也是多种多样:
同平台同版本:Rman+Data Guard(效率高,最常用)
异构平台:exp/expdp+ OGG (FLASHBACK_SCN构造一致性过程中对undo会造成较大压力)、传输表空间(限制条件比较多)、GoldenGate(Keys+Handlecollisions保证初始化过程中事务的完整性,以下简称OGG)、第三方技术等。
异构平台下exp/expdp+ OGG的初始化方式较为常见,下面简单介绍下利用OGG做初始化的方式。
初始化的过程只需要在OGG上配置即可,可大大减少DBA的工作,同时也可以利用OGG对数据不一致的单表做初始化,仅需要将同步表配到同步进程中即可完成表的重新初始化。

Initial Load Group:初始数据加载组,可以分为目标端不转储数据和目标端转储数据两种方式,抽取进程将源端数据抽取并发送到目标端,存储为OGG或者数据库可以识别的数据格式。
Change Extract Group:增量数据,抽取组配合初始数据加载组,完成初始化过程中源端增量数据的同步,保证两端数据一致性。

目标端转储数据:
1File to Replicat:从队列到应用

该方式利用OGG的Initial Load Extract进程将抽取的数据解析成Trail文件,然后将这些Trail文件传输到目标端OGG指定目录里,再由目标端的Replicat进程解析插入到目标数据库中。
2File to Database Utility:队列到数据库功能

该方式源端利用OGG的Initial Load Extract进程解析数据库数据,通过FORMATASCII参数控制将抽取的数据以ASCII格式写入外部文本文件。这些文件可以被Oracle's SQL*Loader,Microsoft's BCP, DTS,SQL Server Integration Services (SSIS),IBM's Load Utility (LOADUTIL)这些数据库加载程序读取并加载,这种方式一般应用于异构的环境,比如 Oracle到IBM的数据库,Oracle到SQL Server之间。
目标端不转储数据:
3GoldenGate Direct Load:OGG直接加载

该方式目标端不转储数据,Initial Load的Extract进程在源端抽取数据并直接发送给目标端的Replicat任务,目标端Replicat任务被Manager进程动态启动,所以不需要Colletor进程收集源端发送的Trail文件,这个过程是大数据块加载。
Direct Bulk Load to SQL*Loader:直接批量加载到SQL*Loader

该方式目标端不转储数据,Initial Load的Extract进程在源端抽取数据并直接发送给目标端的Replicat任务,目标端Replicat任务被Manager进程动态启动,Replicat进程调用SQL*Loader将数据直接写入目标库中,这个过程是直接路径批量加载。

Initial Load Method | Extract Write | Replicat Method | 优缺点 |
File to Replicat | Local Trail | SQL | 速度最慢 源端和目标端都支持数据转换 |
File to Database Utility | External file | Database bulk-load utility | 数据类型必须同时被OGG和数据库功能支持 必须在源端做数据转换 初始化的Replicat进程创建数据库同步需要的控制文件和执行文件 |
Direct Load | Replicat | SQL | 可以在源端和目标端做数据转换 不支持CLOB, NCLOB, BLOB, LONG, XML Repliact以大数据块的形式将数据发送到目标数据库 |
Direct Bulk Load | Replicat | SQL*Loader | 可以在源端和目标端做数据转换 不支持CLOB, NCLOB, BLOB, LONG, XML,UDT. VARRAYS |

源端开启最小附加日志
alter database add supplemental log data;
两端设置OGG参数
alter system set enable_goldengate_replication=true;

create table t1(
id number,
insert_time timestamp(8) not null
)
partition by hash (id) partitions 5;
添加主键
alter table t1 add primary key(id);

begin
for i in 1..2000000
loop
insert into t1 values(i,systimestamp);
commit;
end loop;
end;
/
TEST@orcl1>select count(*) from t1;
COUNT(*)
----------
2000000

添加trandata
dblogin userid goldengate,password goldengate;
add trandata test.*
port 7809
dynamicportlist 7810-7890
purgeoldextracts ./dirdat/*,usecheckpoints, minkeepdays 7
LAGREPORTHOURS 1
LAGINFOMINUTES 30
LAGCRITICALMINUTES 45
初始化进程ext_init
add extract ext_init,sourceistable
参数配置
extract ext_init
userid goldengate, password goldengate
rmthost 192.168.56.3, mgrport 7809
rmttask replicat,group rep_init
table test.t1;
增量数据捕获进程ext_chg
add extract ext_chg, tranlog, begin now
add rmttrail ./dirdat/r1, extract ext_chg
extract ext_chg
setenv (nls_lang=american_america.zhs16gbk)
userid goldengate, password goldengate
rmthost 192.168.56.3, mgrport 7809
rmttrail ./dirdat/r1
table test.t1;

port 7809
dynamicportlist 7810-7890
accessrule, prog *, ipaddr 192.168.56.2, allow 这行参数是为了防止源端与目标端MGR通信时出现Access denied的情况
purgeoldextracts ./dirdat/*,usecheckpoints, minkeepdays 7
LAGREPORTHOURS 1
LAGINFOMINUTES 30
LAGCRITICALMINUTES 45
add replicat rep_init,specialrun
replicat rep_init
userid goldengate, password goldengate
assumetargetdefs
discardfile ./dirrpt/rep_init.dsc, append, megabytes 100
map test.t1, target test.t1;
add replicat rep_chg, exttrail ./dirdat/r1, nodbcheckpoint
replicat rep_chg
setenv (nls_lang=american_america.zhs16gbk)
userid goldengate, password goldengate
handlecollisions 防止应用数据时与目标端已经有数据发生冲突报错
assumetargetdefs
discardfile ./dirrpt/rep_init.dsc, append, megabytes 100
map test.t1, target test.t1;

源端启动捕获进程ext_chg
GGSCI (test1) 14> start ext_chg
Sending START request to MANAGER ...
EXTRACT EXT_CHG starting
GGSCI (test1) 28> info all
info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
EXTRACT RUNNING EXT_CHG 00:00:00 00:00:04
begin
for i in 2000001..5000000
loop
insert into t1 values(i,systimestamp);
commit;
if mod(i,100) = 0 then
dbms_lock.sleep(1);
end if;
end loop;
end;
/
源端启动同步进程ext_init
GGSCI (test1) 31> start ext_init
Sending START request to MANAGER ...
EXTRACT EXT_INIT starting
GGSCI (test1) 32> info ext_init
EXTRACT EXT_INIT Last Started 2018-03-23 13:20 Status RUNNING
Checkpoint Lag Not Available
Process ID 9037
Log Read Checkpoint Table TEST.T1
2018-03-23 13:20:26 Record 1
Task SOURCEISTABLE
GGSCI (test1) 33> info ext_init
info ext_init
EXTRACT EXT_INIT Last Started 2018-03-23 13:20 Status RUNNING
Checkpoint Lag Not Available
Process ID 9037
Log Read Checkpoint Table TEST.T1
2018-03-23 13:20:46 Record 148131
Task SOURCEISTABLE
查看report中部分记录:view report ext_init
***********************************************************************
* ** Run Time Statistics ** *
***********************************************************************
Report at 2018-03-23 13:25:14 (activity since 2018-03-23 13:20:21)
Output to rep_init:
From Table TEST.T1:
# inserts: 2000300
# updates: 0
# deletes: 0
# discards: 0
目标端同步进程rep_init会被源端进程ext_init自动拉起,不用手动启动
GGSCI (test2) 24> info rep_init
REPLICAT REP_INIT Initialized 2018-03-26 11:39 Status RUNNING
Checkpoint Lag 00:00:00 (updated 03:21:59 ago)
Process ID 3989
Log Read Checkpoint Not Available
Task SPECIALRUN
查看report中部分记录:view report rep_init
***********************************************************************
* ** Run Time Statistics ** *
***********************************************************************
Report at 2018-03-26 15:05:58 (activity since 2018-03-26 15:01:06)
From Table TEST.T1 to TEST.T1:
# inserts: 2000300
# updates: 0
# deletes: 0
# discards: 0
当目标端表中的数据量与源端刚启动ext_init进程时表中的数据量一致时,初始化进程会自动停止。
不到5分钟200W条数据,速度还可以,当然这跟你的表结构也有很大关系。
TEST@orcl2>select count(*) from t1;
COUNT(*)
----------
2000300
目标端手动插入部分数据,模拟同步数据主键冲突
insert into t1 values (2000301,systimestamp);
insert into t1 values (2000302,systimestamp);
insert into t1 values (2000303,systimestamp);
insert into t1 values (2000304,systimestamp);
insert into t1 values (2000305,systimestamp);
insert into t1 values (2000306,systimestamp);
insert into t1 values (2000307,systimestamp);
insert into t1 values (2000308,systimestamp);
insert into t1 values (2000309,systimestamp);
insert into t1 values (2000310,systimestamp);
TEST@orcl2>select count(*) from t1;
COUNT(*)
----------
2000310
GGSCI (test2) 28> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT STOPPED REP_CHG 00:00:00 00:41:59
GGSCI (test2) 29> start rep_chg
Sending START request to MANAGER ...
REPLICAT REP_CHG starting
GGSCI (test2) 30> info all
Program Status Group Lag at Chkpt Time Since Chkpt
MANAGER RUNNING
REPLICAT RUNNING REP_CHG 00:09:51 00:00:00
GGSCI (test2) 31> info rep_chg
REPLICAT REP_CHG Last Started 2018-03-26 15:11 Status RUNNING
Checkpoint Lag 00:00:05 (updated 00:00:00 ago)
Process ID 4063
Log Read Checkpoint File ./dirdat/r1000000000
2018-03-26 15:11:55.506069 RBA 8980664
TEST@orcl1>select count(*) from t1;
COUNT(*)
----------
2052700
数据应用正常,没有报错,说明参数handlecollisions生效。
当应用进程rep_chg同步的时间点超过初始化进程rep_init结束的时间点时(即目标端数据开始变化时),通过如下参数关闭rep_chg中的handlecollisions参数。
send replicat rep_chg, nohandlecollisions
本文主要介绍了GoldenGate Initial Load的几种方法,其中Direct Load有着不错的效率,是比较方便的异构平台数据初始化方案,配合增量数据同步进程,可以方便快速的完成数据初始化。点击左下角阅读原文加入我们。
往期精彩文章
__________________________

网易乐得DBA组负责网易乐得电商、网易邮箱、网易技术部数据库日常运维
负责数据库私有云平台的开发和维护
负责数据库及数据库中间件的开发和测试等
分享最前沿实用数据库干货
关注网易乐得DBA
精深数据库神功





