简介:面向Oracle 11g数据库在Windows x64系统上的实时数据复制与迁移,这份压缩包提供Oracle GoldenGate 11.2.1.0.3的完整运行组件,适合DBA、数据集成工程师在Windows Server 2003/2008等64位环境搭建高可用同步链路,解决同构或异构数据库间的低延迟数据分发问题,可用于生产环境数据同步与灾备。包内共185个文件,类型覆盖52个jar(Java扩展)、38个SQL(配置与测试脚本)、17个exe(管理工具)、12个dll(底层依赖库)及txt/xml等说明文档,整体34.1MB,便于离线部署与快速分发。截至目前,该压缩包已有1413人学习,部署时可借助组件理解Extract抽取、Data Pump投递、Replicat应用的关键流程,并配合管理脚本快速验证OGG环境。除核心的Extract、Data Pump、Replicat复制组件外,还包含Management Studio管理界面、trail file变更文件机制、ICU/Xerces运行库及若干示例程序,可辅助理解进程配置与错误日志排查,对规划双向复制、跨版本迁移以及数据一致性校验具有直接实践参考价值。
1. 做数据同步绕不开 Oracle GoldenGate:11.2.1.0.3 是 Oracle 11g + Windows x64 的老牌方案
做数据同步绕不开 Oracle GoldenGate;11.2.1.0.3 这个版本正是为 Oracle 11g + Windows x64 量身准备的老牌方案。项目里最怕业务问一句:“新系统什么时候能看到老系统的订单?”没有跨库触发器、没有定时作业、数据结构又不允许随便重建——Oracle GoldenGate 用日志级捕获就能同时满足表级复制与低侵入。尤其是机房还跑着 Windows Server 2003/2008 的老环境,11.2.1.0.3 几乎是兼容度最稳的一档,既能保住现有系统不拆,又能在目标端把增量数据秒级搬过去。这篇笔记按解压、前置检查、抽取/投递/复制三段进程落地顺序来写,末尾把你必然会撞到的几个坑提前摆出来。第一次摸 OGG 的人,按这个流程走半天,就能看到自己的一对同步进程在跑。
2. 安装包结构与安装前检查:目录、服务注册、库侧五个开关
2.1 解压后先认目录:OGG 的工作目录到底长什么样
Oracle GoldenGate 11.2.1.0.3 for Windows x64 是一个自解压安装包,下载后直接双击解压到磁盘根目录,常见做法是放到C:\OGG或D:\OGG。不建议放进带中文、空格或超长路径的目录。Windows 下路径解析不区分大小写,但底层文件系统对特殊字符的容忍度极差,这一步直接影响后面进程能不能启动。
解压完成后你会看到一组可执行文件和若干子目录。第一次运行前先进入 GGSCI 执行CREATE SUBDIRS,它会自动补齐标准目录结构。先看一眼解压根目录:
C:\OGG │ ggsci.exe # 命令行客户端,所有运维操作都从这里进入 │ mgr.exe # 管理进程可执行文件 │ extract.exe # 抽取/投递进程可执行文件 │ replicat.exe # 复制进程可执行文件 │ libpq.dll # 部分版本需要的支撑库 │ ├─ dirprm # 参数文件目录,MGR/EXTRACT/REPLICAT 参数都放这里 ├─ dirdat # trail 文件目录,默认 ./dirdat/aa 就是它 ├─ dirchk # 检查点文件,进程断点续跑靠它记位置 ├─ dirrpt # 报告文件与日志文件落地目录 ├─ dirdef # 跨平台部署时的定义文件存放处 └─ dircrd # 凭证文件目录这几个目录不需要手动逐个建,CREATE SUBDIRS一次搞定。执行完后dirprm下会有空的参数文件占位,dirdat下会生成两个初始 trail 占位文件。这一步不做不影响解压本身,但后面ADD EXTRACT、START EXTRACT时会报找不到默认 checkpoint 文件,属于典型的“省一步、卡一路”的操作。
2.2 注册 Windows 服务与初始化 GLOBALS 配置
OGG 进程既可以前台运行,也可以注册成 Windows 服务。生产环境我建议注册成服务,重启操作系统后能自动拉起。注册用的是 GGSCI 内置命令,不需要额外辅助脚本:
C:\OGG> ggsci GGSCI> INSTALL ADD SERVICE执行后按提示输入服务名和启动方式。注意两点:一是服务账号要有对整个C:\OGG目录的写权限,否则进程写 trail 文件时报 access denied;二是启动类型选“自动”时,Windows 服务列表里 Oracle 实例服务的启动顺序必须早于 OGG 服务,否则 OGG 起来却连不上数据库,表现为进程反复重启。
注册完服务,还要建 OGG 运行需要的全局配置文件:
GGSCI> EDIT PARAMS ./GLOBALS # 内容只有一行: GGSCHEMA oggEDIT PARAMS是 GGSCI 内置编辑器,保存位置在C:\OGG\GLOBALS。GGSCHEMA ogg指定 OGG 默认使用的数据库模式。生产环境我会单独建一个ogg账号,而不是用system,权限边界清晰,后面参数文件里的USERID都指向它。
2.3 数据库侧先过五个前置项,缺一个后面必然翻车
在把 OGG 进程跑起来以前,源端数据库必须先具备五个条件。按顺序检查:
| 检查项 | 说明 | 验证方法 |
|---|---|---|
| 归档模式 | OGG 从重做日志挖变更,非归档模式下日志一覆盖就断 | ARCHIVE LOG LIST; |
| 强制日志 | 防止 NOLOGGING 操作绕开日志导致丢数据 | SELECT FORCE_LOGGING FROM v$database; |
| 最小补充日志 | OGG 需要额外记录主键/唯一键旧值 | SELECT supplemental_log_data_min FROM v$database; |
| 专用账号权限 | 源端 select any table 与建表权限,目标端增删改权限 | 用DBLOGIN登录验证 |
| 两机系统时间 | Windows 老机器普遍没做 NTP,时差过大会握手失败 | SELECT SYSTIMESTAMP FROM DUAL; |
补充日志这条单独强调。先开数据库级,再开表级:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; -- 之后在 GGSCI 里对业务表开启表级补充日志 GGSCI> DBLOGIN USERID ogg@source, PASSWORD ogg123 GGSCI> ADD TRANDATA source.T_ORDER GGSCI> ADD TRANDATA source.T_CUSTOMER逻辑说明:ADD TRANDATA会根据表结构自动把主键列为补充日志列。表没有主键时,OGG 会尝试用唯一索引兜底。命令执行成功后,源库重做日志里每条 INSERT、UPDATE、DELETE 都会带上新值和旧值的完整影子,OGG 才能正确解析变更并生成 trail 文件。
参数说明:DBLOGIN的USERID用账号@数据库服务名的写法;PASSWORD默认明文存储,11.2.1.0.3 支持用ENCRYPT PASSWORD xxx生成密文放进参数文件,生产环境建议一律用密文。
3. 把双机复制跑起来:EXTRACT、PUMP、REPLICAT 三段进程的参数实战
3.1 一张链路图看懂 OGG 的进程流向
每次带新人我都先让他背三个进程:抽取(Extract)、投递(Data Pump)、复制(Replicat)。数据流向是这样的:
源库重做日志 → Extract 写本地 trail → Pump 网络传输 → 目标端 trail → Replicat 应用
有两种常见变体。小机房里可以只用一个 Extract,直接在参数里写RMTHOST加RMTTRAIL远程写 trail;更稳妥的大机房把 Pump 单独拆出来,让 Extract 只写本地 trail,Pump 专门负责跨机房传输。拆开的好处是源库故障时本地 trail 不丢,网络抖动也不会拖累抽取速度。
先确定同步范围。假设源库模式是source,目标库模式是dest,重点同步两张表:
source.T_ORDER:订单主表,约 150 万行source.T_CUSTOMER:客户表,包含手机号字段
业务指标上,单条 DML 从源库日志写到目标端落地,通常 1 秒内完成;网络延迟大于 20ms 时要适当增大 Pump 的传输窗口,这个体现在RMTHOST参数的网络超时项里。
3.2 源端参数:MGR、EXTRACT、PUMP 三个文件
MGR 管理进程参数写在dirprm/mgr.prm:
PORT 7809 DYNAMICPORTLIST 7810-7829 AUTORESTART EXTRACT *, RETRIES 5, WAITMINUTES 2 PURGEOLDEXTRACTS ./dirdat/*, USECHECKPOINTS, MINKEEPDAYS 3逻辑说明:PORT 7809是 MGR 唯一监听端口,目标端 Pump 通过RMTHOST反向连接这个端口;DYNAMICPORTLIST 7810-7829提供临时端口池,避免两侧防火墙只放通一个端口后传输被随机端口卡住;AUTORESTART EXTRACT *让异常退出的进程自动拉起 5 次,每次间隔 2 分钟;PURGEOLDEXTRACTS是历史 trail 清理规则,MINKEEPDAYS 3表示至少保留 3 天。
参数说明:USECHECKPOINTS会结合检查点文件判断哪些 trail 文件已经安全消费,只有确认不再需要的才清掉,避免手工清理闹出断点事故。
抽取进程参数写在dirprm/e11g.prm:
EXTRACT e11g USERID ogg@source, PASSWORD ogg123 SOURCECHARSET ZHS16GBK EXTTRAIL ./dirdat/aa DISCARDROLLOVER AT 12:00 REPORTCOUNT EVERY 10 MINUTES, RATE TABLE source.T_ORDER; TABLE source.T_CUSTOMER;逻辑说明:EXTTRAIL ./dirdat/aa告诉 Extract 把读到的日志变更写进dirdat\aa这个 trail 序列,后面 Pump 读aa序列再转成bb传到对端。SOURCECHARSET ZHS16GBK声明源库字符集,源库不是这个字符集时不要照抄,要改成实际值,否则中文同步过去全是问号,第四章 4.4 节会展开讲。
参数说明:REPORTCOUNT EVERY 10 MINUTES, RATE让进程每 10 分钟输出一次处理行数与速率到报告文件;DISCARDROLLOVER AT 12:00每天中午 12 点滚动一次废弃记录文件,避免单个 discard 文件无限膨胀占满磁盘。
投递进程参数写在dirprm/pump11.prm:
EXTRACT pump11 USERID ogg@source, PASSWORD ogg123 RMTHOST 192.168.1.20, MGRPORT 7809 RMTTRAIL ./dirdat/bb TABLE source.T_ORDER; TABLE source.T_CUSTOMER;逻辑说明:RMTHOST指定目标端 IP,MGRPORT 7809对应目标端 MGR 的监听端口;RMTTRAIL ./dirdat/bb让目标端把网络包落成本地 trail 文件bb。Pump 进程名虽然是 EXTRACT 开头,但它做的事情是转发,不直接读数据库日志。
3.3 目标端参数:REPLICAT 与 MAP 映射
目标端同样先启动 MGR,再写dirprm/r11g.prm:
REPLICAT r11g USERID ogg@dest, PASSWORD ogg123 ASSUMETARGETDEFS REPERROR DEFAULT, ABEND MAP source.T_ORDER, TARGET dest.T_ORDER; MAP source.T_CUSTOMER, TARGET dest.T_CUSTOMER;逻辑说明:REPERROR DEFAULT, ABEND让复制进程遇到未定义错误直接停止,这是生产环境的标准做法,避免错误被吞掉后两边数据悄悄分叉。ASSUMETARGETDEFS表示两端表结构一致,不额外拉取定义文件;如果列顺序不相同,需要改用SOURCEDEFS并在源端生成 def 文件,做法是执行DEFGEN工具,生成文件放到dirdef目录并在 REPLICAT 里用SOURCEDEFS ./dirdef/source.def指向它。
列映射写法举个例子。目标表列名与源表不一致,但业务上是同一个字段:
MAP source.T_CUSTOMER, TARGET dest.T_CUSTOMER, COLMAP (id_card = source.id_card, cust_name = source.cust_name, masked_mobile = source.mobile);COLMAP 相当于做一次列级换名和转换,目标列在等号左边,源列在右边。它比视图层转换更高效,因为是在复制进程内部完成转换,不经过额外 SQL 往返。注意不要在 COLMAP 里写源表没有的列,否则进程启动时会报 column not found。
3.4 存量数据初始化:SPECIALRUN 模式搬历史表
增量复制只能管住“新产生的变更”,老数据还得搬。常见做法是用数据库工具导一份全量,但更顺滑的方式是借助 OGG 的 SPECIALRUN 进程,一边搬存量一边补增量:
# 源端:新建一个一次性加载 Extract EXTRACT eload USERID ogg@source, PASSWORD ogg123 RMTHOST 192.168.1.20, MGRPORT 7809 RMTFILE ./dirdat/load TABLE source.T_ORDER;# 目标端:一次性复制进程 REPLICAT rload USERID ogg@dest, PASSWORD ogg123 ASSUMETARGETDEFS SPECIALRUN END RUNTIME MAP source.T_ORDER, TARGET dest.T_ORDER;逻辑说明:RMTFILE ./dirdat/load与增量 trail 的RMTTRAIL不同,它生成的是加载专用文件;SPECIALRUN表示进程运行一次即退出,不写检查点,不进入持续运行态。实际操作时,我会先停业务写,记录CURRENT_SCN,把存量数据用导出工具导入目标端,再启动增量进程,最后开业务写。这套顺序能显著缩短停窗时间,避免 SPECIALRUN 和增量进程同时跑造成重复数据。
4. 避坑与排查:Windows 老机房环境下最容易翻车的五件事
4.1 现象:进程起来 10 分钟就 abend,日志提示时间差超过 60 秒
原因:Windows Server 2003/2008 老机器普遍没做 NTP 时间同步,源端和目标端系统时间差一大,OGG 在 TCP 连接握手时校验时间戳失败,进程直接退出。这个现象在跨机房、跨网段部署时尤其常见,因为两边网管策略各管各的。
解决:两台机器加入同一 NTP 域,偏差控制在正负 3 秒以内。Windows 下用w32tm /config /manualpeerlist:ntp_server /syncfromflags:manual /update改完重启 Windows Time 服务。改完后再用SELECT SYSTIMESTAMP FROM DUAL;对比一次两库时间。
4.2 现象:参数文件里写了D:\OGG 数据\dirdat\aa,进程启动报路径不存在
原因:OGG 早期版本对中文路径和空格解析有缺陷,在 Windows 命令行下路径被当成多个 token 切割,GGSCI 解析不准,实际落到文件系统时路径就变了。
解决:安装路径只允许英文字母、数字、下划线。建议固定用C:\OGG或D:\OGG,不要套任何业务缩写中文目录。这条我已经当成团队红线,谁踩谁返工。
4.3 现象:UPDATE 操作没同步,但 INSERT 和 DELETE 都正常
原因:源表没开表级补充日志。OGG 靠补充日志把 UPDATE 的旧值和新值都写进日志,没加ADD TRANDATA时,如果主键列本身没被更新,日志里体现不出旧主键值,Replicat 拿到变更后定位不到目标行,造成更新静默丢失。
解决:重新执行ADD TRANDATA source.T_ORDER;,再查询v$logmnr_contents确认重做日志里确实出现了完整的更新前主键值。表结构变更后也要重新执行一次ADD TRANDATA。
4.4 现象:目标端中文乱码,字符变成“?”
原因:源库字符集 ZHS16GBK、目标库 AL32UTF8,而 Extract 参数里SOURCECHARSET没写,OGG 默认按 UTF-8 解析源日志,中文全变问号。这个在 11g 时代非常典型,很多老库是 ZHS16GBK,新库习惯性建成了 AL32UTF8。
解决:在 Extract 参数文件里补SOURCECHARSET ZHS16GBK。拿不准字符集时,从源库执行SELECT userenv('language') FROM DUAL;查询,再反推到NLS_LANG环境变量。记住原则:源库是什么字符集,SOURCECHARSET就写什么,不要自己去猜目标端应该对标什么。
4.5 现象:归档目录写满,Extract 状态显示 Waiting for archive log
原因:OGG 读取重做日志依赖归档进程,归档目录容量不足时日志无法完成归档,Extract 只能原地等待。表现是进程状态一直 RUNNING,但延迟时间持续拉大,ggserr.log 里反复出现归档等待提示。
解决:先清理或扩容归档目录,再重启归档进程。同时把 MGR 参数里PURGEOLDEXTRACTS MINKEEPDAYS改小到 1 天,配合磁盘空间告警脚本。硬性指标上,归档目录空闲空间建议保持日志日增量的 3 倍以上。
5. 上线后的自检习惯:三连命令加凌晨对账
配好进程后的前 48 小时是事故高危期。我不依赖告警平台,而是交替使用三件套:INFO ALL、STATS和ggserr.log。先从基础命令开始:
# 在 GGSCI 里查看所有进程状态 INFO ALL # 查看复制进程累计处理行数与速率 STATS r11g, TOTALSOFAR # 查看复制进程最近报告 VIEW REPORT r11gINFO ALL看的是进程启动时间和延迟状态,发现 ABEND 立刻拉ggserr.log最后 50 行定位;STATS输出自启动以来各进程处理的总行数与每秒吞吐,判断有没有数据积压;VIEW REPORT交给 DBA 看详细运行报告,落后日志时间超过 5 分钟就要警惕。前 48 小时我每小时跑一遍这三条,直到连续两次结果曲线平稳才降低频率。
如果目标端表有主键,还可以做一个低成本一致性校验:
-- 两库并行执行后对比行数,差异大于阈值时逐条反查 SELECT COUNT(*) FROM source.T_ORDER; SELECT COUNT(*) FROM dest.T_ORDER;超过两张重点表时,我会写脚本在凌晨跑主键集合比对,取两库主键差集再反查。差集为空基本可以判定同步无误,不为空则重点看dirrpt里的错误记录。从那以后我每次上线都强制把“时间同步、补充日志、字符集声明、归档空间”这四项过一遍,确认无报错再往下走。这套习惯让我连续两年没有为 OGG 加过班,希望帮到你。
本文还有配套的精品资源,点击获取